iOS框架弱链接:未定义的符号错误
我正在构build我自己的框架,build议分发给其他开发人员包括他们的项目。 这个框架可选地链接某些框架(例如CoreLocation)。 问题是,当我将框架链接到在构build阶段中不包含CoreLocation的真正的独立项目时,当尝试构build此主机项目时,出现链接器错误,如“未定义的架构符号”
Undefined symbols for architecture x86_64: "_OBJC_CLASS_$_CLLocationManager", referenced from: objc-class-ref in MySDK(MyServerConnection.o) ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
是否有可能避免这种情况,因为我不想强迫开发人员将CoreLocation包含到他们的项目中? 其实,我知道这是可能的,但是我应该怎么做才能做到呢?
从你的问题的描述中,我假设你已经知道如何通过将Xcode设置为“可选”来使Xcode与框架弱连接 。
您需要解决两个问题:类可用性和符号可用性。 Apple在“ 框架编程指南:框架和弱链接”以及“ SDK兼容性指南:使用基于SDK的开发”中介绍了这一点
课程可用性
这非常简单:使用NSClassFromString()
来查看当前环境中的类是否可用。
if (NSClassFromString("CLLocationManager") != NULL){
如果该类可用,则可以实例化并发送消息,否则不能。
符号可用性
你特别感兴趣的是使用弱链接框架的常量或结构。 一个C风格的函数将是类似的,但使用CoreLocation时不担心。 我们将以CoreLocation常量为例。
每次你使用它,你必须检查,以确保它存在:
if (&kCLErrorDomain != NULL){ // Use the constant }
请注意, &
采用常量的地址进行比较。 另外请注意,你不能这样做:
if (kCLErrorDomain){ // Use the constant }
或这个:
if (&kCLErrorDomain){ // Use the constant }
常量符号也可以在运行时使用dlsym查找。 以这种方式使用否定运算符将不起作用。 您必须根据NULL地址检查常量的地址。
我已经提供了一个非常简单的应用程序示例,该应用程序正在使用一个静态库,该库在GitHub上针对Core Location进行弱链接。 示例应用程序不会链接到Core Location:
但是依赖关系可以作为一个可选的(弱)框架:
您可以将任何使用CoreLocation框架的代码和导入包装进去
#ifdef __CORELOCATION__ ... do stuff #endif
当编译时框架没有被链接时,这将取消所有的CoreLocation代码