原始访问器没有可见的@interface

时间:2015-04-22 15:34:45

标签: ios objective-c macos core-data

我正在尝试为简单的瞬态属性实现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:。“ ??

错误是编译错误,而不是警告

生成基元访问器应该有什么特别之处吗?

2 个答案:

答案 0 :(得分:2)

肯定会在运行时自动生成

primitiveFullNamesetPrimitiveFullName。但是在编译时,编译器找不到这些方法。要在调用这些方法时禁止编译错误,您应该声明这些方法的原型。

如果在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本身的答案,而是强烈相关的:

您的实现不方便:如果您有计算属性,则应计算它。你不应该存储它。如果firstNamelastName发生了变化,会发生什么?您是否要将此属性的setter覆盖为nil fullName?如果它是计算属性,请计算它。

- (NSString*)fullName
{
  return [NSString stringWithFormat:@"%@ %@", [self valueForKey:@"firstName"], [self valueForKey:@"lastName"]];
}

完成。

这应该可以解决您的问题,因为它是一个不同的设计。但是,如果您想保留旧方法,可以使用-primitiveValueForKey:-setPrimitiveValue:forKey: