我正在构建我自己的框架,建议将其分发给其他开发人员以包括他们的项目。该框架可选地链接某些框架(例如CoreLocation)。问题是,当我将我的框架链接到在Build Phases中不包含CoreLocation的真实独立项目时,我在尝试构建此主机项目时会收到链接器错误,例如“未定义的架构符号”
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包含在他们的项目中?实际上,我知道这是可能的,但我该怎么做呢?
答案 0 :(得分:11)
根据您对问题的描述,我假设您已经知道如何make Xcode weakly link against the framework将其设置为“可选”。
您需要解决两个问题:类可用性和符号可用性。 Apple在Framework Programming Guide: Frameworks and Weak Linking和SDK Compatibility Guide: Using SDK Based Development
中介绍了这一点这非常简单:使用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地址检查常量的地址。
I have put a very simple example of an application that is using a static library which weak links against Core Location on GitHub. 示例应用程序未链接到核心位置:
但依赖性作为可选(弱)框架:
答案 1 :(得分:1)
您可以在
中包装使用CoreLocation框架的任何代码和导入#ifdef __CORELOCATION__
... do stuff
#endif
当框架未在编译时链接时,这将取消所有CoreLocation代码