实现自定义访问器方法

时间:2013-04-12 18:39:48

标签: cocoa core-data copy

我正在阅读“核心数据编程指南”。它包含以下文字:

  

但是,您必须以符合KVC标准的方式更改属性值。   例如,以下通常表示编程错误:

NSMutableString *mutableString = [NSMutableString stringWithString:@"Stig"]; [newEmployee setFirstName:mutableString]; [mutableString setString:@"Laura"];

  

对于可变值,您应该转移值的所有权   到核心数据,或实现自定义访问器方法,以始终执行   复制。如果是类,前面的示例可能不表示错误   表示Employee实体声明了firstName属性   (复制)(或实现了一个自定义的setFirstName:方法,复制了   新价值)。在这种情况下,调用setString后:(在   第三个代码行)firstName的值仍然是“Stig”和   不是“劳拉”。

关于文本的问题:“在这种情况下”是哪种情况 - 属性被声明为“复制”或不属于?

关于复制和编程实践的问题: 从我在这里读到: NSString property: copy or retain? 我明白了

  1. 使用副本将确保firstName是“Stig”,而不是Laura
  2. 这样做是明智的,因为“在几乎所有情况下,你都希望防止在其背后改变对象的属性”
  3. 我真的想知道上面引用的文字是什么,试图在核心数据的背景下告诉我们。无论是否使用核心数据,我们都必须使用“复制”。另外,如果有人可以在上面的点“2”(对......来说是明智的)上投入更多的光线,我会很高兴,因为在它背后改变一个物体属性的后果是什么?

2 个答案:

答案 0 :(得分:1)

你的“有关文字的问题:”在这种情况下“是哪种情况 - 财产被宣布为”复制“或不是? 我认为,与Apple文件要解释的观点不符。

正如Apple文档指出的那样,如果正常实现custom-accessor-method,则默认实现会 NOT 复制属性值。如果属性值可能是可变的并且实现了NSCopying协议(例如NSString的情况),则可以在自定义访问器中复制该值以帮助保留封装(例如,在实例的情况下, NSMutableString的值作为值传递)。

这是一个复制设置器代码段

@interface Department : NSManagedObject
{
}
@property(nonatomic, copy) NSString *name;
@end
@implementation Department
@dynamic name;
- (void)setName:(NSString *)newName
{
    [self willChangeValueForKey:@"name"];
    // NSString implements NSCopying, so copy the attribute value
    NSString *newNameCopy = [newName copy];
    [self setPrimitiveName:newNameCopy];
    [self didChangeValueForKey:@"name"];
} @end

答案 1 :(得分:0)

问题是何时使用(以及如何)不可变值。

由于核心数据在检测到对象所做的更改时会大量使用KVO,如果使用直接通过其对象而不是通过属性更改的可变属性,CoreData将不会检测到对象的更改,并且您的更改可能不会持久到商店。

如果使用可变的NSManagedObject属性,则覆盖setter / getter方法并仅使用它们来改变底层对象(这意味着您有责任让CoreData知道对象发生了更改,并且必须保留到商店。
此外,如果对复杂对象使用可变形属性,则必须自己触发更改通知,以便CoreData意识到发生了更改,并且在上下文保存时应该重新转换并保存对象。 / p>

我强烈建议当涉及字符串之类的简单对象时,使用不可变属性值会强制您浏览对象属性并触发默认KVO通知(复制属性也会强制执行KVO通知)。 / p>