我正在使用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或在此类实现中提供方法实现
我完全不知道这里发生了什么。它开始煮沸我的血液一点点。我错过了什么?
答案 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