我正在尝试为简单的瞬态属性实现getter方法。 transient属性是fullName属性。 fullName = firstName + lastName。
的典型示例我正在开发一个iOS应用程序(以防万一在OS X上的相关内容有所不同)
遵循'掌握核心数据'WWDC 2010 Keynote我为Person NSManagedObject子类创建了一个类别。在那个类别中,我添加了以下方法:
- (NSString *)fullName {
[self willAccessValueForKey:@"fullName"];
NSString *fullName = [self primitiveFullName];
[self didACCessValueForKey:@"fullName"];
if (fullName == nil) {
fullName = [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
[self setPrimitiveFullName:fullName];
}
return fullName;}
Person类已由Xcode自动创建,并具有fullName属性及其在@dynamic中的实现。
当我尝试编译项目时,我收到此类别的错误,上面写着“没有可见的@interface为'Person'声明了选择器'primitiveFullName'”。
当Apple文档说“为什么我收到此错误”时,例如,给定具有属性firstName的实体,Core Data会自动生成firstName,setFirstName:,primitiveFirstName和setPrimitiveFirstName:。“ ??
错误是编译错误,而不是警告
生成基元访问器应该有什么特别之处吗?
答案 0 :(得分:2)
primitiveFullName
和setPrimitiveFullName
。但是在编译时,编译器找不到这些方法。要在调用这些方法时禁止编译错误,您应该声明这些方法的原型。
如果在2010年,Objective-C编译器只会发出警告来调用那些未申报的方法。但是在ARC推出之后,Objective-C编译器不允许调用这种未声明的方法。
如下所示:
@interface Person (PrimitiveAccessors)
- (NSString *)primitiveFullName;
- (void)setPrimitiveFullName:(NSString *)newName;
@end
@implementation Person (TransientProperties)
- (NSString *)fullName {
[self willAccessValueForKey:@"fullName"];
NSString *fullName = [self primitiveFullName];
[self didAccessValueForKey:@"fullName"];
if (fullName == nil) {
fullName = [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
[self setPrimitiveFullName:fullName];
}
return fullName;
}
@end
答案 1 :(得分:2)
对你的设计的第一个评论不是Q本身的答案,而是强烈相关的:
您的实现不方便:如果您有计算属性,则应计算它。你不应该存储它。如果firstName
或lastName
发生了变化,会发生什么?您是否要将此属性的setter覆盖为nil fullName
?如果它是计算属性,请计算它。
- (NSString*)fullName
{
return [NSString stringWithFormat:@"%@ %@", [self valueForKey:@"firstName"], [self valueForKey:@"lastName"]];
}
完成。
这应该可以解决您的问题,因为它是一个不同的设计。但是,如果您想保留旧方法,可以使用-primitiveValueForKey:
和-setPrimitiveValue:forKey:
。