如何构建Objective-C静态库以作为单个二进制文件和头文件进行分发?

我正在Objective-C中为iOS构建一个静态库MyLibrary ,它将十几个有用的类捆绑在一起,每个类都有自己的.h文件。 我想将MyLibrary分发为单个编译二进制文件libMyLibrary.a和单个.h头文件MyLibraryAPI.hMyLibraryAPI.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.aMyLibraryAPI.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)。