duplicate symbol是一種常見的連結錯誤,不像編譯錯誤那樣可以直接定位到問題的所在。但是經過一段時間的總結,發現這種錯誤總是有一些規律可以找的。
例如,我們有如下的最簡單的兩個類代碼:
// ClassA.h
#import <Foundation/Foundation.h>
@interface ClassA : NSObject
@end
// ClassA.m
#import "ClassA.h"
@implementation ClassA
// ClassB.h
@interface ClassB : NSObject
// ClassB.m
#import "ClassB.h”
@implementation ClassB
編譯後出現的錯誤資訊如下:
duplicate symbol _OBJC_METACLASS_$_ClassA in:
/Users/dajie/Library/Developer/Xcode/DerivedData/linkTest-cpjaaatiyqpvxcbzfzpklcbqrgqg/Build/Intermediates/linkTest.build/Debug-iphonesimulator/linkTest.build/Objects-normal/i386/ClassA.o
/Users/dajie/Library/Developer/Xcode/DerivedData/linkTest-cpjaaatiyqpvxcbzfzpklcbqrgqg/Build/Intermediates/linkTest.build/Debug-iphonesimulator/linkTest.build/Objects-normal/i386/ClassB.o
duplicate symbol _OBJC_CLASS_$_ClassA in: /Users/dajie/Library/Developer/Xcode/DerivedData/linkTest-cpjaaatiyqpvxcbzfzpklcbqrgqg/Build/Intermediates/linkTest.build/Debug-iphonesimulator/linkTest.build/Objects-normal/i386/ClassA.o
/Users/dajie/Library/Developer/Xcode/DerivedData/linkTest-cpjaaatiyqpvxcbzfzpklcbqrgqg/Build/Intermediates/linkTest.build/Debug-iphonesimulator/linkTest.build/Objects-normal/i386/ClassB.old: 2
duplicate symbols for architecture i386clang:
error: linker command failed with exit code 1 (use -v to see invocation)
從上面出現問題的地方,我們應該能推測出是ClassA這個類出了問題。如果這個類是我們自己寫的,就容易辦一些。
可以考慮以下原因:
1.引入頭檔案時,由于疏忽,誤引入.m檔案。這種一般仔細檢查一下出現問題的類的源檔案就能發現。
例:ClassB.m 檔案修改成下面這樣
#import "ClassB.h>"
#import "ClassA.m” // 這句話有問題
2.同一個類,實作兩次,即有兩個@implementation 。這種一般會有一個警告,也比較容易發現。
例:ClassB.m檔案修改成下面這樣:
// ClassB.m
3.工程檔案,同一個類檔案被引入了兩次,引起這種錯誤的原因大概有兩種:一是多人協作開發時,導緻project檔案合并沖突;二是同名檔案不在同一目錄下,添加到工程時造成重複添加。 這種一般在檔案視圖,用名字過濾器檢查一下就發現了。
4. Targets的Build Phase設定項裡,檢視Complie Sources這一項,看看出現問題的類是不是有重複的,用檔案名過濾也比較容易發現。這種問題一般也是多人協作開發時,project檔案沖突導緻的。發現這種問題,隻要删除就可以了。不過在我解決問題過程中,删除其中一個檔案時,重複檔案會自動全部删除,是以還需要單獨添加一下。
5.如果我們的工程中引用了第三方的庫,而恰好第三方的庫裡面有一個ClassA,也會出現這種問題。如果不能修改第三方的庫代碼,隻能修改我信自己的代碼了。
待完善