【问题标题】:With CoreData, if I have an @dynamic property, can I override its getter just like it was @synthesized? (Lazy Instantiation)使用 CoreData,如果我有一个 @dynamic 属性,我可以像 @synthesized 一样覆盖它的 getter 吗? (惰性实例化)
【发布时间】:2013-04-06 17:08:10
【问题描述】:

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

【问题讨论】:

  • 它说_preview 是一个未声明的标识符,因为您没有具有该名称的变量。 @synthesize 创建变量; @dynamic 没有。

标签: ios objective-c core-data nsmanagedobject


【解决方案1】:

一种标准方法是在Core Data 模型中将preview 定义为transient 属性(这样该值实际上并不存储在数据库中),并实现自定义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。)

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

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

更新: Core Data Programming Guide 的当前版本 不再包含该章节。您可以找到存档版本 来自Way Back Machine。当然,这必须与 一粒盐,因为它不是官方文档的一部分 没有了。

【讨论】:

  • @satheeshwaran:谢谢。
  • 只需要使用那个方法吗?或者我必须在 CoreData 文件中做些什么?
  • @user212541:应该就是这样。您只需在 Core Data 模型编辑器中将预览属性标记为瞬态。
  • 它究竟是如何复制数据的?
  • @SAHM:是的,不幸的是,Apple 删除了 Core Data Programming Guide 的几个章节以及最近的更新(您可能想向 Apple 提交错误报告!)。我在我的答案中添加了一个存档版本的链接。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2014-03-12
    • 2012-06-30
    • 1970-01-01
    • 2015-12-10
    • 2011-08-25
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 2012-02-21
    相关资源
    最近更新 更多