使用 CoreData,如果我有一个 @dynamic 属性,我可以像 @synthesized 一样覆盖它的 getter 吗? (惰性实例化)
Posted
技术标签:
【中文标题】使用 CoreData,如果我有一个 @dynamic 属性,我可以像 @synthesized 一样覆盖它的 getter 吗? (惰性实例化)【英文标题】:With CoreData, if I have an @dynamic property, can I override its getter just like it was @synthesized? (Lazy Instantiation) 【发布时间】: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
没有。
【参考方案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"];
【讨论】:
以上是关于使用 CoreData,如果我有一个 @dynamic 属性,我可以像 @synthesized 一样覆盖它的 getter 吗? (惰性实例化)的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法为 Core Data 原始访问器自动生成 @property 和 @dynamic 标签?
如果没有数据,带有 @FetchRequest (SwiftUI) 和 NSPredicate 的 CoreData 会崩溃