Part1:问题描述
- 最近一直被这个错误烦,我自己的情况是这样的,公司项目用
git管理,我不小心在Pods下的第三方框架里新建了一个文件(如下图所示),我们约定趁这个文件叫做SB文件。之后编译了一次,后来意识到文件位置错了,我就把文件移出来,再重新放到需要的位置上。然后重新编译,Bulid Success。 - 晚上回家把项目运行到自己电脑上,就报错,报的是我删除的文件没有添加到编译,然后我去
Build Phases里的Compile Sources中查看,我后来添加的文件确实没有参与编译,然后我就把报错的文件添加到Compile Sources。然后重新编译,Bulid Success。
-
第二天上班,把昨晚的项目拷贝到公司电脑,
Command + R运行,就报了duplicate symbol _OBJC_CLASS_$_XXX错误。然后我把SB文件从编译中去掉,然后重新编译,Bulid Success。 -
晚上回到家,一运行项目,又开始报
SB文件没有参与编译,然后又添加编译,然后重新编译,Bulid Success。第三天来到公司,又报duplicate symbol _OBJC_CLASS_$_XXX错误。然后我把SB文件从编译中去掉,然后重新编译,Bulid Success。 -
......
-
问题大致可以描述成这样,在家里的电脑上我需要将这个文件添加到
Compile Sources,但是在公司电脑上,我必须把这个文件从Compile Sources中删除。所以每次在不同的电脑上运行前,我需要先把文件或者删或者添加完成。 -
这个问题没解决之前,我一直这样干,你能想象我的心情吗?
Part2:错误分析
-
这个错误要注意“duplicate(重复) symbol(标识)”,这个词的意思是出现“_ 标识 _”重复。
-
这个标识可以是一个关键词,比如你在全局常量里定义了一个
kSpaceGobel标示,然后在某一个文件里,又定义了一个常量也叫作kSpaceGobel,这个时候编译就会报这个错误。 -
还有就是,你
#import “xxx.h”时,手疾眼快,直接把“.m”文件当成“.h”文件导入到某一类里。 -
网上说的最多的也就是上面两种情况,这两种情况我都熟悉。显然,我的错误不是这两种当中的一种。
Part 3:问题解决
-
如果你项目里的某个文件不参与编译,那么 Clang编译器 不会将这个文件加入编译,也就是说,你在这个文件里写代码,是没有语法提醒的。
-
我的问题解决方法是,最后是我自己跑到_/Users/你的用户名/Library/Developer/Xcode/DerivedData_ 下把这个文件夹下的所有文件全部删除了。然后重新编译,
Bulid Success。 -
关于
_DerivedData_这个文件夹,我去Google上找了一下,没看到有详细说明这个文件夹作用的文献。我说个自己个人的猜想,不一定准确,仅作为你的参考。 -
我猜想:Xcode 会将第一次编译好的文件保存在这个文件夹里,以后你再次运行的时候,Xcode会监测你更改了哪些文件,再次编译的时候就只编译那些你更改了的文件,再与原先编译好的文件合成,就可以运行了,这样就能避免你每次按下
command + R的时候都要从零开始编译,从而提高工作效率。这个猜想的来源是,你第一次运行一个大的项目时进度条会走的很慢,但是一旦你运行过一次,以后再次运行的时候就会很快。 -
需要强调的是,这个文件是唯一的,也就是说,每台 Mac 上的这个文件都是不一样的。所以,如果你以后也碰到类似,在一台电脑上跑的好好的项目,拷贝到另外一台电脑上就报莫名其妙的错误,大抵你应该来这个文件夹下看看。