簡體   English   中英

Objective-C中的子類NSArray

[英]Subclass NSArray in Objective-C

我需要一個類,它具有NSArray的所有方法,其行為方式相同,但修改了2個方法。

我想在我的自定義類中覆蓋這兩個方法:

1)countByEnumeratingWithState:objects:count:

2)objectAtIndex:

經過數小時的研究,我認為沒有任何合理的方法,因為:

  • 我不想使用類別,因為並非所有NSArray實例都應該具有修改后的行為。 (加上警告)

  • 我不想重寫所有初始化程序加上所有的arrayWith ...方法+原始方法+實現我自己的存儲(因為這個功能已經在Cocoa中實現了,對不對?為什么我要重新實現一個已經在那里的班級?)

  • 如果我讓自定義類繼承NSObject並使用NSArray作為ivar中的存儲,那么在Xcode中編程時,所有NSArray的方法都不可用(即使我可以將它們轉發到NSArray ivar)

  • 我通過使用method_setImplementation(...)按需覆蓋方法實現取得了一些成功,但仍然無法找到一種方法來動態創建在運行時創建的類,然后將自定義實現我提到的2種方法。

期待您的想法! 謝謝

Mantra:如果某些事情很難(或者看起來它需要的代碼多於必要的代碼),那么您的設計很可能與iOS / OS X框架的設計原理背道而馳。 它可以為重新審視您的設計提供更好的解決方案。


要回答原始問題,如果要子類化NSArray(或NSMutableArray),則需要實現原始方法,不多也不少。

原始方法是在類本身的@interface中聲明的方法。 即:

@interface NSArray : NSObject
- (NSUInteger)count;
- (id)objectAtIndex:(NSUInteger)index;
@end

對於NSMutableArray:

@interface NSMutableArray : NSArray
- (void)addObject:(id)anObject;
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
- (void)removeLastObject;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
@end

如果您繼承NSMutableArray並實現上述7個方法(NSArray中的兩個方法),那么您將擁有一個兼容的NSMutableArray子類 - 假設您的方法已正確實現 - 所有API都使用可變數組。

這是因為類集群的設計方式。 公共課是抽象的; 永遠不會直接實例化。 它們提供了一個原始接口,它包含類的核心功能,然后是根據原語實現的所有其他非原始API(除了初始化器,見下文)的具體實現。 然后,具體的私有子類覆蓋所有基元和一些非基元,以便為特定配置提供最佳行為。

我想為我正在處理的庫創建一個NSArray實例,我想讓它為我的庫用戶透明地工作。 IE瀏覽器。 對於他們來說,使用普通的NSArray和我將要提供的修改后的類別應該沒有區別。 IE瀏覽器。 它是一個存儲問題,最終用戶不應該關注它,並且接口應該保持與NSArray相同 - 因此在這一點上失去所有init方法並不是一個真正的選擇。

初始化方法不是 NSArray的原始接口的一部分。 您正在添加一個要求,除了文檔中定義的“使類與NSArray / NSMutableArray兼容”之外。 沒問題,只是指出來。

之所以出現這種情況,是因為將集合類子類化以提供您描述的業務邏輯非常罕見。 集合在其行為方面非常通用,而條件化集合行為的此類業務邏輯將在管理整個模型層對象圖的類中完成。

如果你真的想這樣做,提供你想要的任何init*方法的實現,根據需要調用你的包裝通用實例。 初始化器的實現沒有什么特別之處,你這樣做會失去很多。

也不需要實現所有這些。 實現一個或兩個,並在其余部分上@throw描述性異常。

如果您決定轉發接受var-args的那些,則不能直接,因為沒有va_list接受方法。 相反,您需要將參數的va_list轉換為語言數組(即id[] foo = malloc(... * sizeof(id)); )並將其傳遞給initWithObjects:count: .

其他一些評論:

  • 你正在做什么[在子類中提供完整的NS * Array接口]似乎很難,因為它不是一個常見的模式,框架設計者認為沒有必要創建一個支持它的設計。 原始集合級別的自定義行為幾乎總是在對象圖中的更高級別更好地實現。 幾乎總是如此。

  • method_setImplementation()和動態類創建在學術上很有趣,但幾乎從來都不是解決方案。 顯然,使用NSArray或NSMutableArray類(或具體實現類)進行混亂將會破壞依賴於標准行為的其余框架。 除此之外,它是一種動態OO組合模式,並不是真正用於Objective-C; 維持這個屁股會很痛苦。

而不是子類化NSArray為什么不創建一個基於包含NSArray的NSObject的新類?

然后你可以使用NSArray的所有功能並添加你自己的方法,用它來做自定義操作?

或者你需要一個NSArray?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM