2011-07-03 74 views
5

我已經有了Objective-C類有一個屬性需要是集合類(通常是NSArray)的各種情況。有沒有一個標準的方式來實現這一點?如果能夠使用@synthesize來設置它,那將是非常好的。我可以將屬性聲明爲NSMutableArray和@synthesize,但這不允許我強制哪些類型的對象可以放入集合中,也不會阻止客戶端代碼修改該數組。我通常做的是這樣的:目標C @屬性對於多對多關係

@property(nonatomic, readonly) NSArray *widgets; 

- (void)addWidget:(Widget*)widget; 
- (void)removeWidget:(Widget*)widget; 
... 

集合被實現爲一個NSMutableArray,包含一個NSArray傳遞返回給調用者的當前內容。這似乎是很多編碼必須是常見的情況。爲了建立關鍵值觀測,還需要做更多的編碼工作。

我是否錯過了一些東西,還是真的需要設置一個集合屬性來工作?

回答

1

您可以通過將屬性聲明爲NSArray,但使用NSMutableArray作爲存儲機制來阻止客戶端代碼修改您的數組。 @property和@synthesize指令仍然有效。

確實沒有一種確保數組返回的對象的類型安全性的好方法,但Objective-C程序員幾乎從不擔心這一點。它不是一個普遍的問題。如果你真的想確保只有某種類型的對象進入並從數組中出來,你將不得不爲NSArray編寫一個包裝類來完成。

+0

用你描述的方法,我仍然需要編寫添加/刪除方法,所以我想我可以在那裏執行類型。我將不得不測試一下這是否會影響KVO的合規性。我希望這會是因爲我現在直接操縱屬性的存儲變量而不是自己處理單獨的可變集合。 – brentopolis

+0

我還注意到,將屬性聲明爲NSArray實際上並不妨礙客戶端代碼修改數組,因爲實際返回的對象是NSMutableArray。它只會導致編譯器警告。 – brentopolis

+0

正確的是,當您聲明該屬性的類型爲NSArray時,合成訪問器方法仍然會返回內部NSMutableArray對象的retain-auroreleased實例。您的API的用戶不應該嘗試將該對象轉換爲NSMutableArray,因爲API只承諾NSArray。但是,如果你正在編寫一個廣泛使用的公共API,這個API很難實施。在這種情況下,您仍然可以使用@synthesize指令,但實現getter方法,以便它返回一個自動釋放的伊娃的副本,例如。 'return [[_myMutableArray copy] autorelease];' – Ryan