2009-06-03 54 views
7

閱讀鍵 - 值編碼編程指南後,鍵 - 值觀察編程指南模型對象實現指南,以及關於該主題閱讀許多StackOverflow的條目,並與各種建模場景試驗,我覺得我對如何建模數據有很好的把握。應該將「一對多」關係建模爲屬性嗎?

我最終使用所有屬性和一對一關係的聲明屬性,由私有ivars支持。對於需要私密寫入的只讀屬性,我使用.h接口聲明中的readonly屬性,然後在.m文件中聲明的類擴展中使用readwrite屬性重新聲明該屬性。在類方法中,我總是使用帶有點語法的屬性訪問器,並且從不直接訪問私有ivars。

然而,仍然有一個方面仍然讓我感到困惑:如何正確建模多對多關係,特別是當集合是公開不可變的,但是私有可變的(即模型對象的消費者不能添加或移除對象到集合,但集合的內容由班級私人管理)。

我知道如何實現KVC訪問器方法以實現多對多關係(countOf<Key>,objectsIn<Key>AtIndex等),這是我到目前爲止所遵循的路線。但是,我已經看到了一些示例代碼,它使用聲明的屬性來公開關係,不實現KVC訪問器方法,但仍然可以觀察Key-Value。例如:

@interface MyModel : NSObject 
{ 
    // Note that the ivar is a mutable array, 
    // while the property is declared as an immutable array. 
    @private NSMutableArray *transactions_; 
} 

@property (nonatomic, retain, readonly) NSArray transactions; 

@end 

-------------------- 

@implementation MyModel 

@synthesize transactions = transactions_; 

- (void)privateMethodThatManagesTransactions 
{ 
    [[self mutableArrayValueForKey:@"transactions"] addObject:t]; 
} 

@end 

如果你的消費對象將自己作爲一個MyModel實例爲"transactions"關鍵路徑的觀察者,無論何時交易都添加或從transactions集合中刪除,將被通知(只要突變通過mutableArrayValueForKey:方法完成)。

對我來說,這似乎是最簡潔的方式來公開多對多關係,因爲我不需要手動編寫集合KVC訪問器,並且它保持代碼清潔。

但是,它似乎並沒有被Apple文檔推廣的方式,我不禁想知道它的作用是否僅僅是一種不可靠的副作用。

因此,在我開始研究一個項目的實際模型類中提到一種技術或其他技術之前,我想獲得有經驗的Cocoa開發人員的意見和建議。

所以問題是:如果我使用屬性來建模多對多關係,我還需要實現KVC訪問器/增變器方法嗎?

更新

即使當我宣佈一個一對多的財產readonly,如上面的例子中,外部代碼仍然可以調用模型對象mutableArrayValueForKey:@"transactions"和變異的集合。這似乎表明,使用已申報屬性進行多對多關係並不是一種可行的方式,但我仍然覺得我並不完全瞭解它......

+0

我只是認識到,即使對於表示屬性或簡單的屬性對一的關係,聲明屬性中.H和重新聲明爲在.M讀寫允許外部碼作爲只讀通過使用更改的屬性值KVC setValue:forKey:...因此,似乎KVC允許在所有情況下繞過屬性聲明中表達的語義,所以我猜我不應該驚訝於能夠通過使用mutableArrayValueForKey改變只讀集合:.. 。 – 2009-06-04 15:44:23

回答

6

是的。

然而,有它仍然讓我不解的一個方面:如何正確多對多關係模式,特別是當收集是要公開不變,但私下裏可變...。

簡單說明:在頭文件中聲明屬性爲readonly,然後在執行文件中聲明redeclare it as readwrite, copy in a class extension

我明白瞭如何實現多對多關係(countOf<Key>objectsIn<Key>AtIndex等)KVC存取方法,這是我到目前爲止一直在跟隨的路線。

也有變化的。有了這些,你不需要使用mutableArrayValueForKey:;相反,你可以直接使用變種訪問器。您仍然會收到KVO通知,因爲KVO會在第一次將這些方法添加爲該屬性的觀察者時自動包裝這些方法。

我在我的博客上有a list of the accessor selector formats,包括可變訪問器。

編輯:

即使當我宣佈一個一對多的特性爲只讀,就像上面的例子中,外部代碼仍然可以調用模型對象mutableArrayValueForKey:@"transactions"和變異的集合。

這是一個很好的理由,使它成爲一個習慣使用變化的訪問器,並避免mutableArrayValueForKey:。如果您嘗試使用編譯器警告(沒有這種[公共]方法),您將不會從課堂外發送突變消息。

儘管mutableArrayValueForKey:和有人會使用它的風險的可用性,KVO兼容的屬性的方式去這裏。

+0

感謝您的快速回答。我編輯了我的問題,使其更加精確:如果我使用屬性來建模多對多關係,是否仍然需要實現KVC訪問器/增變器方法? – 2009-06-03 19:30:09