iOS Framework弱链接:未定义符号错误 [英] iOS Framework weak link: undefined symbols error

查看:174
本文介绍了iOS Framework弱链接:未定义符号错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建自己的框架,建议将其分发给其他开发人员以包括他们的项目。该框架可选地链接某些框架(例如CoreLocation)。问题是,当我将我的框架链接到在Build Phases中不包含CoreLocation的真实独立项目时,我在尝试构建此主机项目时会收到​​链接器错误,例如未定义的架构符号

I'm building my own framework which proposed to be distributed to other developers for including to their projects. This framework links optionally certain frameworks (e.g. CoreLocation). The problem is that when I link my framework to real stand-alone project which doesn't contain CoreLocation in Build Phases, I'm getting linker errors like 'Undefined symbols for architecture' when tryin to build this host-project

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包含在他们的项目中?实际上,我知道这是可能的,但我该怎么做才能实现这个目标?

Is it possible to avoid this because I don't want to force developers to include CoreLocation to their projecgts? Actually, I know it's possible, but what should I do to achieve this?

推荐答案

从你的问题描述中,我假设您已经知道如何使Xcode与框架弱连接将其设置为可选。

From the description of your issue, I assume you already know how to make Xcode weakly link against the framework by setting it as 'Optional'.

您需要解决两个问题:类可用性和符号可用性。 Apple在框架编程指南:框架和弱链接 SDK兼容性指南:使用基于SDK的开发

You have two problems to solve: Class availability and symbol availability. Apple covers this in the Framework Programming Guide: Frameworks and Weak Linking and the SDK Compatibility Guide: Using SDK Based Development

这非常简单:使用 NSClassFromString()查看该类是否在当前环境中可用。

This is pretty straightforward: use NSClassFromString() to see if the class is available in the current environment.

if (NSClassFromString("CLLocationManager") != NULL){

如果该类可用,则可以实例化并发送消息,否则不能。

If the class is available it can be instantiated and sent messages, otherwise it cannot.

您特别感兴趣的是使用来自弱链接框架的常量或结构。 C风格的功能类似,但在使用CoreLocation时不需要考虑这些功能。我们将使用CoreLocation常量作为示例。

What you are specifically interested in is using constants or structs from a weakly linked framework. A C-style function would be similar, but those are not a concern when using CoreLocation. We'll use a CoreLocation constant as an example.

每次使用它时,必须检查以确保它存在:

Every time you use it you MUST check to make sure it exists:

if (&kCLErrorDomain != NULL){
   // Use the constant
}

请注意& 获取常量的地址以进行比较。
另请注意,您不能这样做:

Note that the & takes the address of the constant for the comparison. Also note that you CANNOT do this:

if (kCLErrorDomain){
   // Use the constant
}

或者这个:

if (&kCLErrorDomain){
   // Use the constant
}

也可以使用 dlsym
以这种方式使用否定运算符将不起作用。您必须根据NULL地址检查常量的地址。

Constant symbols can also be lookup up at runtime using dlsym. Using the negation operator in this way will not work. You must check the address of the constant against the NULL address.

我已经提供了一个非常简单的应用程序示例,该应用程序正在使用静态库,该库与GitHub上的Core Location弱链接。 示例应用程序未链接到Core Location:

但依赖性作为可选(弱)框架:

这篇关于iOS Framework弱链接:未定义符号错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆