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

use*_*541 19 core-data objective-c nsmanagedobject ios

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

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

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

    return _preview;
}
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*n R 28

一种标准方法是在Core Data模型中定义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;
}
Run Code Online (Sandbox Code Playgroud)

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

如果您需要preview重新计算,如果body属性发生变化,则还必须实现自定义的setter方法为body,设置previewnil.

有关更多信息,请阅读"核心数据编程指南"中的非标准持久属性.

更新:核心数据编程指南的当前版本不再包含该章节.您可以从Way Back Machine找到存档版本.当然,由于它不再是官方文档的一部分,因此必须采取一些措施.


Dan*_*lly 6

请参阅使用文档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"];
}
Run Code Online (Sandbox Code Playgroud)