蘋果推薦解決:
解決方法為:找到 target 的圖標(biāo),更改其 Other Linker Flags 為: -all_load 或 -force_load
-force_load骇扇,后跟隨一個(gè)文件位置档押,可以更精確地加載所需文件窖维。
簡(jiǎn)單點(diǎn)說就是啦吧,Objective-C 的動(dòng)態(tài)特性使得需要,為鏈接器添加一個(gè)標(biāo)簽(設(shè)置 Other Linker Flags 為 -ObjC)來解決通過 Category 向類添加方法的問題璃搜。
但這個(gè)標(biāo)簽 -ObjC 在 64 位 和 iOS 中有問題拖吼,需要使用 -all_load 或 -force_load。
總結(jié)如下:
如果这吻,第三庫中沒有 category绿贞,Other Linker Flags 無需設(shè)置
如果,第三方庫中有 category橘原,需要設(shè)置為 -ObjC
如果籍铁,某些 Xcode 版本中,出現(xiàn)問題趾断,修改設(shè)置為 -all_load
鏈接:
http://stackoverflow.com/questions/2567498/objective-c-categories-in-static-library
$(OTHER_LDFLAGS) -ObjC
http://www.blogjava.net/lincode/archive/2012/04/23/376373.html
http://developer.apple.com/library/mac/#qa/qa1490/_index.html
目前最好解決:
鏈接:http://www.dreamingwish.com/dream-2012/the-create-the-static-the-library-containing-the-category.html
一拒名、異常的原因
在連接一個(gè)含有category的靜態(tài)庫的時(shí)候,往往會(huì)得到一個(gè)運(yùn)行時(shí)exception “selector not recognized”芋酌。
這是由于 UNIX的靜態(tài)庫實(shí)現(xiàn)增显、linker和Objective-C的動(dòng)態(tài)結(jié)構(gòu)三者之間的問題引起的。
Objective-C并不為每個(gè)函數(shù)定義linker symbol脐帝,它只為每個(gè)class生成linker symbol同云。(objc的動(dòng)態(tài)結(jié)構(gòu))
如果你為一個(gè)已存在的class創(chuàng)建了category,那么linker并不知道要將原始class實(shí)現(xiàn)和category實(shí)現(xiàn)聯(lián)系起來堵腹。這就導(dǎo)致了最終程序中的對(duì)象沒法響應(yīng)category中的方法炸站。
要解決這個(gè)問題,只要在build靜態(tài)庫時(shí)疚顷,加上linker flag “-ObjC”即可(在64位osx上和iOS程序上旱易,這樣做還不夠)禁偎,這個(gè)flag告訴linker將每個(gè)定義了class或者category的對(duì)象文件都載入靜態(tài)庫。
二阀坏、iOS程序還需要做的
用xcode4.3創(chuàng)建lib時(shí)如暖,-ObjC這個(gè)flag默認(rèn)是有的(之前的版本不記得了,好像4.x版本的都會(huì)默認(rèn)帶這個(gè)參數(shù))忌堂,但是最終程序還是會(huì)拋這個(gè)異常盒至,這是因?yàn)閘inker的bug,對(duì)于64位osx程序和iOS程序士修,這個(gè)bug導(dǎo)致只包含category而不包含class的文件沒法從靜態(tài)庫中加載枷遂。
所以,apple建議我們?yōu)橐罱K程序的linker加上-all_load或者-force_load參數(shù)李命。
-all_load選項(xiàng)強(qiáng)制linker加載所有包中的所有對(duì)象文件登淘,即使文件中沒有Objective-C代碼也加載箫老。-force_load是從Xcode3.2開始有的封字,它使得linker獲取包加載的控制權(quán),每個(gè)-force_load參數(shù)后面都必須跟上一個(gè)包的路徑耍鬓,然后這個(gè)包的所有對(duì)象文件都會(huì)被加載阔籽。
懶人使用-all_load,勤快人使用-force_load牲蜀。笆制。。
但是這樣始終不好涣达,因?yàn)檫@兩個(gè)選項(xiàng)都可能導(dǎo)致不必要的代碼被加載在辆。
三、更好的方法
Three20庫給出了一個(gè)宏:
#define TT_FIX_CATEGORY_BUG(name) @interfaceTT_FIX_CATEGORY_BUG_##name @end@implementatio TT_FIX_CATEGORY_BUG_##name @end
為每個(gè)只包含category的文件的category實(shí)現(xiàn)前面加上這樣一個(gè)宏(定義一個(gè)空的class)度苔,此時(shí)不再需要-all_load或者-force_load匆篓,因?yàn)椴淮嬖谥话琧ategory的文件。linker的bug也就無從體現(xiàn)寇窑。