为什么不声明实例变量?

时间:2013-01-15 19:39:46

标签: ios objective-c compiler-errors warnings

我正在使用xcode 4.5.2和LLVM 4.1。我希望我不需要合成一个类属性,也不需要声明一个实例变量,但我收到的错误表明这些期望是错误的。

我的课程:

@interface Test : NSManagedObject
@property (strong, nonatomic) NSString *string;
@property (strong, nonatomic) NSString *number;
@end

@implementation Test
- (NSString*)string {
    return _string;
}
@end

1)使用未声明的标识符'string'

我还在WWDC 2010会议144中看到了以下内容:

return self->string;

但是建议使用点表示法时会出错。

2)在'Test *'类型的对象上找到属性'string';你的意思是用“。”来访问它。操作者吗

我也收到number的警告:

3)属性'number'需要定义方法'number' - 使用@synthesize,@ dynamic或在此类实现中提供方法实现

我完全不知道这里发生了什么。它开始煮沸我的血液一点点。我错过了什么?

2 个答案:

答案 0 :(得分:5)

首先,点符号是你的朋友!

其次,当您尝试使用->时,您必须访问ivar。在最新版本的Xcode和LLVM中,如果您未使用@synthesize自行指定,则会为您创建带有下划线的ivar。

所以你会做self->_string。您在使用推荐的.时访问该属性。这也可能是您number收到警告的原因,因为self->number不存在。


编辑:为了回应您使用NSManagedObject的事实,我绝对建议使用属性(如Todd推荐的那样)。 NSManagedObjects希望你使用@dynamic,因为Core Data会做很多事情,Apple建议你不要改变它。

如果你想要一个自定义的getter / setter,我会推迟使用primitive方法的another SO question

- (NSString *)name
{
    [self willAccessValueForKey:@"name"];
    NSString *myName = [self primitiveName];
    [self didAccessValueForKey:@"name"];
    return myName;
}

当然,Apple Docs on the matter。以及与iOS 6相关的related question/solution

答案 1 :(得分:2)

如果同时为属性实现setter和getter方法,那么编译器会假定您也在处理后备存储,并且不会为您创建_string实例变量。

您可以手动声明它,也可以使用@synthesize string = _string;强制编译器为您声明它。后者将基于属性类型为ivar提供正确的内存管理语义(强,弱等)。

对于托管对象,您需要实现MishieMoo的答案,但这是您的NSObject子类没有问题中所述的_string变量的原因。

更详细地介绍了here