如何构建Objective-C静态库以作为单个二进制文件和头文件进行分发?
我正在Objective-C中为iOS构建一个静态库MyLibrary
,它将十几个有用的类捆绑在一起,每个类都有自己的.h文件。 我想将MyLibrary
分发为单个编译二进制文件libMyLibrary.a
和单个.h头文件MyLibraryAPI.h
。 MyLibraryAPI.h
有十几个#import
语句,一个用于MyLibrary
的十几个公共类。 想要在其宿主项目中包含MyLibrary
开发人员只需要包含libMyLibrary.a
二进制文件和MyLibraryAPI.h
头文件。 这是目标。
所以我已经将MyLibrary
Xcode项目中每个公共类的Role
设置为Public
并使用Xcode命令行build utils和lipo
成功构建了libMyLibrary.a
。 然后,我在主机项目中手动包含所有十二个MyLibrary
头文件和libMyLibrary.a
,并且宿主项目可以使用公共MyLibrary
类没有问题。 真棒!
问题是,如果我删除那些十二个头文件并改为使用MyLibraryAPI.h
(这是我的目标),主机项目的类将无法再找到MyLibrary
引用的MyLibrary
头文件。 相反,在编译时,我得到如下错误: MyAwesomeThingDelegate.h: No such file or directory...
对于我尝试在MyLibraryAPI.h
#import
每个MyLibrary
类, MyAwesomeThingDelegate.h: No such file or directory...
。 我的主机项目根目录中有一个名为lib
的文件夹,并且在主机项目构建设置中已将递归头搜索路径设置为lib/**
并且在库搜索路径中,设置了lib/**
的递归路径。
我很想听听社区关于如何正确设置主机项目的搜索路径的建议,这样我只需要包含libMyLibrary.a
和MyLibraryAPI.h
来使用MyLibrary
类。 或者,如果我做错了什么,我很想听到另一个建议,即实现我分发单个二进制文件和单个API头文件的目标。
我遇到了同样的挑战,我得到了以下解决方案:
首先,我试图隐藏尽可能多的实现细节。 出于这个原因,我通常构建成对的类:一个类是公共接口,另一个类是私有实现。 公共类只有一个成员实例:指向实现的指针。 私人class级只有一个前瞻性声明。
@class MyViewImpl; @interface MyView : UIView { @private MyViewImpl* _internal; } @property (nonatomic, assign) CGRect highlightArea; - (void) startAnimation; @end
其次,我将所有公共声明放入单个头文件中。 与单独的头文件一样使用起来很舒服,但它有效。 剩下的唯一导入是iOS内容的导入,例如:
#import
我在这里用另一种方法给出第二个答案。
Objective C的工作方式是,编译器需要库的用户直接调用的所有类的完整声明(即头文件)。 库文件(.a文件)仅包含已编译的代码而不包含声明。 它仅由链接器使用,这是构建应用程序的最后步骤之一。
[C或C ++等编程语言是相同的。 然而,Java或C#等编程语言会在编译代码中存储有关类的元信息,因此它们不需要头文件,只需要.jar或.dll文件。
因此,一种方法是将.a和目录充满头文件给用户。 然后,他们将.a文件添加到他们的项目中,在他们使用类的任何地方添加一个#import语句,并将头文件目录的路径添加到他们的构建设置(称为Header Search Paths)。