20

使用 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 文件中。我对惰性实例化有什么不同?

4

2 回答 2

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;
}

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

如果您需要在属性更改时preview重新计算body,那么您还必须实现一个自定义的 setter 方法以body将其设置previewnil.

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

更新:当前版本的核心数据编程指南不再包含该章节。您可以从Way Back Machine中找到存档版本。当然,这必须持保留态度,因为它不再是官方文档的一部分。

于 2013-04-06T17:20:51.830 回答
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"];
}
于 2013-04-06T17:18:24.543 回答