使用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文件中。懒惰实例化它有什么不同呢?
答案 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"];
}