3 回答

TA貢獻(xiàn)1921條經(jīng)驗(yàn) 獲得超9個(gè)贊
如果您不需要同時(shí)使用兩個(gè)框架中的類,并且您的目標(biāo)是支持NSBundle卸載的平臺(tái)(OS X 10.4或更高版本,沒有GNUStep支持),并且性能對您來說確實(shí)不是問題,我相信你可以在每次需要使用一個(gè)類時(shí)加載一個(gè)框架,然后在需要使用其他框架時(shí)卸載它并加載另一個(gè)框架。
我最初的想法是使用NSBundle加載其中一個(gè)框架,然后復(fù)制或重命名該框架內(nèi)的類,然后加載另一個(gè)框架。這有兩個(gè)問題。首先,我找不到復(fù)制指向重命名或復(fù)制類的數(shù)據(jù)的函數(shù),而第一個(gè)框架中引用重命名類的任何其他類現(xiàn)在將從其他框架引用該類。
如果有方法可以復(fù)制IMP指向的數(shù)據(jù),則無需復(fù)制或重命名類。您可以創(chuàng)建一個(gè)新類,然后復(fù)制ivars,方法,屬性和類別。還有更多的工作,但這是可能的。但是,您仍然會(huì)遇到引用錯(cuò)誤類的框架中的其他類的問題。
編輯:C和Objective-C運(yùn)行時(shí)之間的根本區(qū)別在于,據(jù)我所知,當(dāng)加載庫時(shí),這些庫中的函數(shù)包含指向它們引用的任何符號(hào)的指針,而在Objective-C中,它們包含字符串表示形式。 thsoe符號(hào)的名稱。因此,在您的示例中,您可以使用dlsym在內(nèi)存中獲取符號(hào)的地址并將其附加到另一個(gè)符號(hào)。庫中的其他代碼仍然有效,因?yàn)槟鷽]有更改原始符號(hào)的地址。Objective-C使用查找表將類名映射到地址,并且它是1-1映射,因此您不能擁有兩個(gè)具有相同名稱的類。因此,要加載這兩個(gè)類,其中一個(gè)必須更改其名稱。但是,當(dāng)其他類需要訪問其中一個(gè)具有該名稱的類時(shí),

TA貢獻(xiàn)1776條經(jīng)驗(yàn) 獲得超12個(gè)贊
使用唯一前綴為您的類添加前綴基本上是唯一的選擇,但有幾種方法可以減少繁瑣和丑陋。還有就是選擇一個(gè)長時(shí)間的討論在這里。我最喜歡的是@compatibility_aliasObjective-C編譯器指令(在此描述)。您可以使用@compatibility_alias“重命名”類,允許您使用FQDN或某些此類前綴命名您的類:
@interface COM_WHATEVER_ClassName : NSObject
@end
@compatibility_alias ClassName COM_WHATEVER_ClassName
// now ClassName is an alias for COM_WHATEVER_ClassName
@implementation ClassName //OK
//blah
@end
ClassName *myClass; //OK
作為完整策略的一部分,您可以為所有類添加前綴,例如FQDN,然后創(chuàng)建一個(gè)包含所有內(nèi)容的標(biāo)頭@compatibility_alias(我想您可以自動(dòng)生成所述標(biāo)頭)。
這樣的前綴的缺點(diǎn)是你必須COM_WHATEVER_ClassName在除編譯器之外的字符串中需要類名的任何東西中輸入真正的類名(例如上面)。值得注意的是,@compatibility_alias是一個(gè)編譯器指令,而不是運(yùn)行時(shí)函數(shù),因此NSClassFromString(ClassName)將失?。ǚ祷豱il) - 您將不得不使用NSClassFromString(COM_WHATERVER_ClassName)。您可以使用ibtoolvia build階段在Interface Builder nib / xib中修改類名,這樣就不必在Interface Builder中編寫完整的COM_WHATEVER _...
最后的警告:因?yàn)檫@是一個(gè)編譯器指令(并且是一個(gè)模糊的指令),它可能無法跨編譯器移植。特別是,我不知道它是否適用于LLVM項(xiàng)目的Clang前端,盡管它應(yīng)該與LLVM-GCC(使用GCC前端的LLVM)一起使用。

TA貢獻(xiàn)1825條經(jīng)驗(yàn) 獲得超6個(gè)贊
有些人已經(jīng)分享了一些可能有助于解決問題的棘手和聰明的代碼。一些建議可能有效,但所有這些建議都不太理想,其中一些建議非常難以實(shí)施。(有時(shí)丑陋的黑客是不可避免的,但我盡量避免使用它們。)從實(shí)際的角度來看,這是我的建議。
無論如何,請告知開發(fā)人員沖突的兩個(gè)框架,并明確表示他們未能避免和/或處理沖突會(huì)導(dǎo)致您遇到真正的業(yè)務(wù)問題,如果解決這個(gè)問題,可能會(huì)導(dǎo)致業(yè)務(wù)收入損失。強(qiáng)調(diào)雖然在每個(gè)類的基礎(chǔ)上解決現(xiàn)有的沖突是一個(gè)不那么具有侵入性的解決方案,但是完全改變它們的前綴(或者如果它們當(dāng)前不是,那么使用它們,并且對它們感到羞恥!)是確保它們不會(huì)的最佳方法。再次看到同樣的問題。
如果命名沖突僅限于一組相當(dāng)小的類,請查看是否可以解決這些類,特別是如果您的代碼之一未直接或間接使用其中一個(gè)沖突類。如果是,請查看供應(yīng)商是否將提供不包含沖突類的框架的自定義版本。如果沒有,請?zhí)孤实卣f,他們?nèi)狈`活性會(huì)降低您使用框架的投資回報(bào)率。不要因?yàn)樵诤侠矸秶鷥?nèi)咄咄逼人而感到沮喪 - 客戶永遠(yuǎn)是對的。;-)
如果一個(gè)框架更“可有可無”,您可以考慮將其替換為另一個(gè)框架(或代碼組合),無論是第三方還是自制程序。(后者是不受歡迎的最壞情況,因?yàn)樗隙〞?huì)產(chǎn)生額外的業(yè)務(wù)成本,無論是開發(fā)還是維護(hù)。)如果你這樣做,請告知該框架的供應(yīng)商你決定不使用他們的框架的原因。
如果兩個(gè)框架被認(rèn)為對您的應(yīng)用程序同樣不可或缺,請?zhí)剿鲗⑵渲幸粋€(gè)框架的使用分解為一個(gè)或多個(gè)單獨(dú)進(jìn)程的方法,也許可以通過DO進(jìn)行通信,如Louis Gerbarg建議的那樣。根據(jù)溝通的程度,這可能沒有你想象的那么糟糕。我相信有幾個(gè)程序(包括QuickTime)使用這種方法通過在Leopard中使用Seatbelt沙箱配置文件提供更細(xì)粒度的安全性,這樣只允許代碼的特定子集執(zhí)行關(guān)鍵或敏感操作。性能將是一種權(quán)衡,但可能是您唯一的選擇
我猜測許可費(fèi),條款和持續(xù)時(shí)間可能會(huì)阻止對這些點(diǎn)的即時(shí)行動(dòng)。希望您能夠盡快解決沖突。祝好運(yùn)
- 3 回答
- 0 關(guān)注
- 1945 瀏覽
添加回答
舉報(bào)