3 回答
TA貢獻1921條經驗 獲得超9個贊
如果您不需要同時使用兩個框架中的類,并且您的目標是支持NSBundle卸載的平臺(OS X 10.4或更高版本,沒有GNUStep支持),并且性能對您來說確實不是問題,我相信你可以在每次需要使用一個類時加載一個框架,然后在需要使用其他框架時卸載它并加載另一個框架。
我最初的想法是使用NSBundle加載其中一個框架,然后復制或重命名該框架內的類,然后加載另一個框架。這有兩個問題。首先,我找不到復制指向重命名或復制類的數據的函數,而第一個框架中引用重命名類的任何其他類現在將從其他框架引用該類。
如果有方法可以復制IMP指向的數據,則無需復制或重命名類。您可以創建一個新類,然后復制ivars,方法,屬性和類別。還有更多的工作,但這是可能的。但是,您仍然會遇到引用錯誤類的框架中的其他類的問題。
編輯:C和Objective-C運行時之間的根本區別在于,據我所知,當加載庫時,這些庫中的函數包含指向它們引用的任何符號的指針,而在Objective-C中,它們包含字符串表示形式。 thsoe符號的名稱。因此,在您的示例中,您可以使用dlsym在內存中獲取符號的地址并將其附加到另一個符號。庫中的其他代碼仍然有效,因為您沒有更改原始符號的地址。Objective-C使用查找表將類名映射到地址,并且它是1-1映射,因此您不能擁有兩個具有相同名稱的類。因此,要加載這兩個類,其中一個必須更改其名稱。但是,當其他類需要訪問其中一個具有該名稱的類時,
TA貢獻1776條經驗 獲得超12個贊
使用唯一前綴為您的類添加前綴基本上是唯一的選擇,但有幾種方法可以減少繁瑣和丑陋。還有就是選擇一個長時間的討論在這里。我最喜歡的是@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,然后創建一個包含所有內容的標頭@compatibility_alias(我想您可以自動生成所述標頭)。
這樣的前綴的缺點是你必須COM_WHATEVER_ClassName在除編譯器之外的字符串中需要類名的任何東西中輸入真正的類名(例如上面)。值得注意的是,@compatibility_alias是一個編譯器指令,而不是運行時函數,因此NSClassFromString(ClassName)將失敗(返回nil) - 您將不得不使用NSClassFromString(COM_WHATERVER_ClassName)。您可以使用ibtoolvia build階段在Interface Builder nib / xib中修改類名,這樣就不必在Interface Builder中編寫完整的COM_WHATEVER _...
最后的警告:因為這是一個編譯器指令(并且是一個模糊的指令),它可能無法跨編譯器移植。特別是,我不知道它是否適用于LLVM項目的Clang前端,盡管它應該與LLVM-GCC(使用GCC前端的LLVM)一起使用。
TA貢獻1825條經驗 獲得超6個贊
有些人已經分享了一些可能有助于解決問題的棘手和聰明的代碼。一些建議可能有效,但所有這些建議都不太理想,其中一些建議非常難以實施。(有時丑陋的黑客是不可避免的,但我盡量避免使用它們。)從實際的角度來看,這是我的建議。
無論如何,請告知開發人員沖突的兩個框架,并明確表示他們未能避免和/或處理沖突會導致您遇到真正的業務問題,如果解決這個問題,可能會導致業務收入損失。強調雖然在每個類的基礎上解決現有的沖突是一個不那么具有侵入性的解決方案,但是完全改變它們的前綴(或者如果它們當前不是,那么使用它們,并且對它們感到羞恥?。┦谴_保它們不會的最佳方法。再次看到同樣的問題。
如果命名沖突僅限于一組相當小的類,請查看是否可以解決這些類,特別是如果您的代碼之一未直接或間接使用其中一個沖突類。如果是,請查看供應商是否將提供不包含沖突類的框架的自定義版本。如果沒有,請坦率地說,他們缺乏靈活性會降低您使用框架的投資回報率。不要因為在合理范圍內咄咄逼人而感到沮喪 - 客戶永遠是對的。;-)
如果一個框架更“可有可無”,您可以考慮將其替換為另一個框架(或代碼組合),無論是第三方還是自制程序。(后者是不受歡迎的最壞情況,因為它肯定會產生額外的業務成本,無論是開發還是維護。)如果你這樣做,請告知該框架的供應商你決定不使用他們的框架的原因。
如果兩個框架被認為對您的應用程序同樣不可或缺,請探索將其中一個框架的使用分解為一個或多個單獨進程的方法,也許可以通過DO進行通信,如Louis Gerbarg建議的那樣。根據溝通的程度,這可能沒有你想象的那么糟糕。我相信有幾個程序(包括QuickTime)使用這種方法通過在Leopard中使用Seatbelt沙箱配置文件提供更細粒度的安全性,這樣只允許代碼的特定子集執行關鍵或敏感操作。性能將是一種權衡,但可能是您唯一的選擇
我猜測許可費,條款和持續時間可能會阻止對這些點的即時行動。希望您能夠盡快解決沖突。祝好運
- 3 回答
- 0 關注
- 1965 瀏覽
添加回答
舉報
