使用CoreData,如果我有@dynamic属性,我可以像@synthesized一样覆盖它的getter吗? (懒惰实例化)

时间:2013-04-06 17:08:11

标签: ios objective-c core-data nsmanagedobject

使用CoreData我创建了一个实体,然后将其子类化为自己的文件,其中包含@propertys,然后它在.m文件中包含@dynamic部分。

当我希望某些东西具有某个值时,如果它从未被设置过,我总是使用惰性实例化,如下所示:

- (NSString *)preview {
    if ([self.body length] < 200) {
        _preview = self.body;
    }
    else {
        _preview = [self.body substringWithRange:NSMakeRange(0, 200)];
    }

    return _preview;
}

但是如何使用@dynamic属性执行此操作?如果我做同样的事情,它说_preview是一个未声明的属性,但它在.h文件中。懒惰实例化它有什么不同呢?

2 个答案:

答案 0 :(得分:28)

一种标准方法是在核心数据模型中将preview定义为瞬态属性(以便该值实际上不存储在数据库中),并实现自定义getter方法。在你的情况下,它看起来像:

- (NSString *)preview
{
    [self willAccessValueForKey:@"preview"];
    NSString *preview = [self primitiveValueForKey:@"preview"];
    [self didAccessValueForKey:@"preview"];
    if (preview == nil) {
        if ([self.body length] < 200) {
            preview = self.body;
        } else {
            preview = [self.body substringWithRange:NSMakeRange(0, 200)];
        }
        [self setPrimitiveValue:preview forKey:@"preview"];
    }
    return preview;
}

(您可以为@dynamic属性提供自定义getter,setter方法。但是,Core Data 属性不是简单地由实例变量备份。这就是你不能的原因 访问_preview。)

如果preview属性发生变化,您需要重新计算body,那么您 还必须为body实施自定义setter方法,将preview设置回nil

有关详细信息,请阅读“核心数据编程指南”中的Non-Standard Persistent Attributes

更新:核心数据编程指南的当前版本 不再包含那一章了。您可以找到存档版本 来自Way Back Machine。当然这必须采取 因为它不是官方文件的一部分所以是一粒盐 了。

答案 1 :(得分:6)

See documentation使用primitiveValueForKey:

基本上是:

@dynamic name;

- (NSString *)name
{
    [self willAccessValueForKey:@"name"];
    NSString *myName = [self primitiveName];
    [self didAccessValueForKey:@"name"];
    return myName;
}

- (void)setName:(NSString *)newName
{
    [self willChangeValueForKey:@"name"];
    [self setPrimitiveName:newName];
    [self didChangeValueForKey:@"name"];
}