iOS经典错误Undefined symbols for architecture XXX:

首先声明

因为我是在真机上编译的项目,所以报错的架构(CPU指令集)为arm64。

  • 如果我们使用64位模拟器(iPhone simulators 5s 或更高版本)编译或者运行项目,就会报以下错误:
    • Undefined symbols for architecture x86_64:
  • 如果我们使用32位模拟器(iPhone simulators 5 或更低版本)编译或者运行项目,就会报以下错误:
    • Undefined symbols for architecture i386:

Undefined symbols for architecture XXX:类似的错误是一个开发中经常遇到的问题,凡是涉及到第三方静态库的项目,都不可避免的遇到过这一类错误。为了说明错误的原因和加深对解决方案的理解。笔者采用了故意复现问题的方式来验证问题的解决方案:
即:故意给工程进行错误的配置或者删除某些配置,使工程编译不通过,然后记下编译器报的错误,验证什么情况下会报这种错。
首先声明,我的工程中引用(并非通过cocoapods引用)了友盟的统计SDK,名称叫做libMobClickLibrary.a。存储在工程的third_party目录下,如下图:


静态库目录

原因之一:没有链接lib库而报错

lib是library的意思,lib库就是指后缀名为.a的静态库。
(1) 删除General -> Linked Frameworks and Libraries 下的libMobClickLibrary.a。如下图分别是删除前和删除后的对比:

删除前:


此时链接了静态库

删除后:


此时不再链接静态库

(2) 再次真机编译项目,我们就能如愿以偿的看到两个经典的的错误 "OBJC_CLASS$_MobClick", referenced from: 和 linker command failed with exit code 1 (use -v to see invocation),点击第一个错误,如下图:

Snip20161219_11.png

(3)然后看到 Undefined symbols for architecture arm64:


Snip20161219_4.png

但是我们怎么知道是没有链接libMobClickLibrary.a库而不是其他的什么库呢?这还要取决于这句"_OBJC_CLASS_$_MobClick", referenced from:。其中_OBJC_CLASS_$_MobClick中的MobClick就是我们引用的libMobClickLibrary.a中的一个文件。因为我真的是在AliyunSalesCustomerListTableViewManager.m中通过#import "MobClick.h"引用了MobClick.h,如下图:

Snip20161219_12.png

当然,如果我们引用了libMobClickLibrary.a库中的其他文件,那么OBJC_CLASS$_后面就不是MobClick了,这个大家应该是很好理解的。

有的时候,因为后面的类名跟第三方的库名没有任何相似处,比如库名叫做libAAA.a,而报错的类名却是BBB。此时,我们通过后面的类名根本不能准确的判断出这个BBB属于哪个库,也就不知道该链接哪个库。这种情况下,我们可以通过referenced from:提示后面的文件名来判断BBB到底属于哪个静态库,因为我们自己的某个类文件不太可能import很多第三方的库,这种情况下,采取这种方式比较好判断。

总结:综上,我们可知:项目中如果用到了某个第三方静态库,但lib静态库或者framework静态库没有被链接时,就会遇到Undefined symbols for architecture XXX这一类的错误。
** 原因:**编译项目时,因为静态库没有链接进工程,所以静态库就不会参与编译,而项目某些文件(.m文件)又引用(或者说依赖)了静态库,所以自然会报错,而报的错就是经典的 Undefined symbols for architecture XXX这一类的错误。
解决方案:下次遇到这类问题,我们只需要在Linked Frameworks and Libraries 中添加指定的静态库即可!


还原项目

因为刚才删除了libMobClickLibrary.a文件,我们要想让项目可以恢复到完美编译运行的状态,需要在Linked Frameworks and Libraries 添加libMobClickLibrary.a库,如下图:

因为是第三方库,不是系统提供的库,所以需要到我们自己的目录中添加:如下图展示了添加步骤:

第一步:点击添加
第二步:点击Add Other
第三步:选中静态库点击open

至此,缺失的静态库已经被链接进工程中,再次编译项目就不会报这个错误。当然,如果还报类似错误,说明你的项目中还需要链接其他的静态库,链接方法相同。

原因之二:没有链接.framework静态库而报错

上面说明了工程中因为缺少链接lib库导致报错的一种情况。iOS开发中有两种格式的静态库(.a格式和.framework格式)。所以,我们也不难猜测:缺少链接.framework格式的静态库也会导致同样的错误。
如果我们引用的第三方库并不是.a格式的静态库,而是.framework格式的静态库,在Linked Frameworks and Libraries中没有被链接的情况下,也会报同样的错误。比如我在Linked Frameworks and Libraries 中删除 PushCenterSDK.framework静态库(这个静态库存在于木纹中,不是cocoapods管理的),如下图:
(1)在Linked Frameworks and Libraries中删除PushCenterSDK.framework


删除.framework静态库

(2)模拟器编译项目,出现以下三个错误:


因为缺少链接的静态库所以编译出现错误

(3)点击第一个错误,查看错误详情,如下图:


错误详情

发现:如果缺少链接.framework格式的静态库,也会报相同的错误,所以,不管我们缺少链接的是.a静态库还是.framework静态库,只要在Link Frameworks and Libraries 中没有正确链接进去,都会报相同的错误,即:Undefined symbols for architecture XXX:。

值得注意的是,此处报了三个错误,原因在于,YunFuPushCenter.m文件中引用了PushCenterSDK.framework的两个文件(如下图),所以会多报一个错误,这个是比较好理解的:


引用了framework中的两个文件

原因之三:extern引用不存在的全局变量而报错

开发中,我们很有可能用到全局变量,比如在delegate.m文件中定义了一个int 型全局变量globalVar,在ViewController.m文件中通过extern int globalVar; 而引用A.m文件的这个全局变量。这样是没问题。但是如果我们不小心把extern int globalVar 写成 extern int globalVariate,且在ViewController.m文件中使用了这个globalVariate变量(代码如下)。

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

int globalVar; // 生命一个全局变量
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    return YES;
}
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

extern int globalVariate; // 引用一个不存在的全局变量
- (void)viewDidLoad {
    [super viewDidLoad];
    
    globalVariate = 10; // 给不存在的全局变量赋值
}

@end

编译上面代码也会报同样的错误,如下图:


点击错误查看详情,如下图:


原因:因为extern int globalVariate并没有定义名为globalVariate的变量,而是引用了一个名字叫做globalVariate的全局变量。当我们使用globalVariate时候,系统发现这个变量根本没有定义,就会报这个错误。

原因之四:Compile Sources中没有添加对应的.m文件而报错

有时候,我们项目中并没有以静态库的形式引用第三方库,而是直接使用的三方源码。也有可能出现相同的错误。如下图:
项目中以源码的形式引用了react native。某一次执行了git pull命令后,再编译项目,就出现了下面这个错误。其意为:RCTSegmentedControlManager.m文件引用了RCTSegmentedControl文件,但是找不到RCTSegmentedControl.m这个文件(.h文件是不参与编译的)。同理,RCTScrollView.m文件和RCTRefreshControlManager.m文件中引用了RCTRefreshControl.m文件,但是也找不到RCTRefreshControl.m文件。


图片.png

于是乎,我们去Build Phases -> Compile Sources中搜索RCTRefreshControl或者RCTSegmentedControl,确实没有找到对应的.m文件。如下图1和图2:


图1
图2

于是,把这两个.m文件加进去,如下图1和图2:


图1
图2

最终,再次command + R,编译通过!
综上,如果某个.m文件没有被添加在Compile Sources中,那么这个.m文件就不会参与编译,导致其他文件引用该文件时,就会报错: Undefined symbols for architecture XXX: 解决办法,就是把这个.m文件添加到Compile Sources中。

文/VV木公子(简书作者)
PS:如非特别说明,所有文章均为原创作品,著作权归作者所有,转载请联系作者获得授权,并注明出处,所有打赏均归本人所有!

如果您是iOS开发者,或者对本篇文章感兴趣,请关注本人,后续会更新更多相关文章!敬请期待!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • 静态库与动态库的区别 首先来看什么是库,库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别...
    吃瓜群众呀阅读 11,911评论 3 42
  • 一。每次遇到这种错误就头痛,不知道要害死多少脑细胞了,就在这里做个总结吧 可能会遇到这几种错误: Undefine...
    ttdiOS阅读 13,547评论 2 11
  • 这几天公司有一个新的需求,就是要将我们开发的某些东西都抽取出来,打个比方我们开发了A项目,可以以后B项目要包含A项...
    黄鱼儿啦啦啦阅读 6,153评论 2 16
  • (原文:How to Create a Framework for iOS作者:Sam Davies 译者:Mr_...
    Yaanco阅读 2,327评论 4 5
  • 本来打算今天在家预习,毕竟还有一个星期就开学了,高一,想考好点。可是妈妈叫我去店里帮忙一天,把还没做完的工作做好,...
    夜儿阅读 168评论 0 0