在阅读了Key-Value Coding Programming Guide、Key-Value Observing Programming Guide和Model Object Implementation Guide,以及阅读了很多关于该主题的 StackOverflow 条目并尝试了各种建模场景之后,我感觉我对如何为我的数据建模。
我最终为我的所有属性和一对一关系使用声明的属性,由私有 ivars 支持。对于需要私有可写的只读属性,我readonly
在接口声明中使用该属性,然后在文件中声明的类扩展中使用该属性.h
重新声明该属性。在类方法中,我总是使用带点语法的属性访问器,从不直接访问私有 ivars。readwrite
.m
然而,有一个方面仍然让我感到困惑:如何正确建模多对关系,特别是当集合是公开不可变但私有可变时(即模型对象的消费者不能向集合添加或删除对象,但是集合的内容由类私下管理)。
我确实了解如何为一对多关系( , 等)实现 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"
模型对象并改变集合。这似乎表明对多对关系使用声明的属性不是要走的路,但我仍然觉得我不太明白......