在Xcode工程的Other linker flags中添加-ObjC 標志可以解決使用靜態庫中的category時出現unrecognized selector的問題。
UNIX的靜態庫(xxx.a)其實就是一個目標文件(xxx.o)的集合。在C語言中,編譯一個源文件時如果遇到在其他文件中定義的函數,則會留下一個 undefined symbol。在鏈接時會通過找到其他文件中的定義來確定這個symbol。
在Objective-C中,由于方法調用都是在運行期確定的,因此沒有針對方法的symbol,只有針對類的。
這樣在靜態庫中如果使用了category擴展已有的類,編譯器不知道如何將category和已有的類整合在一起,就會導致unrecognized selector問題。添加-ObjC標志后,編譯器會把一個類相關的所有目標文件都加載,這樣就解決了這個問題。但是由于這樣做會使可執行文件體積變大,所以沒有設為默認選項。
在64位ios應用環境下,由于鏈接器的一個bug,在靜態庫中只有category沒有對應的class定義時,-ObjC標志會失效。這時可以使用-all_load強制加載所有目標文件,或者使用-force_load指定加載某一個包。
在Xcode4.2之后,這個鏈接器bug已經被修復,因此-all_load 和 -force_load標志都不再需要了。在必要時添加-ObjC即可。