我试图理解一些人用来区分实例变量和属性的策略.常见的模式如下:
@interface MyClass : NSObject { NSString *_myVar; } @property (nonatomic, retain) NSString *myVar; @end @implementation MyClass @synthesize myVar = _myVar;
现在,我认为这个策略背后的整个前提是可以很容易地区分出伊达和财产之间的区别.所以,如果我想使用由合成属性继承的内存管理,我会使用如下内容:
myVar = @"Foo";
另一种方式是通过自我引用它.[ivar/property here].
使用@synthesize myVar = _myVar策略的问题是,我认为编写代码如:
myVar = some_other_object; // doesn't work.
编译器抱怨myVar未声明.为什么会这样?
谢谢.
属性只是设置器和getter ivars
,应该(几乎)总是使用而不是直接访问.
@interface APerson : NSObject { // NSString *_name; // necessary for legacy runtime } @property(readwrite) NSString *name; @end @implementation APerson @synthesize name; // use name = _name for legacy runtime @end
@synthesize
在这种情况下创建这两种方法(不是100%准确):
- (NSString *)name { return [[_name copy] autorelease]; } - (void)setName:(NSString *)value { [value retain]; [_name release]; _name = value; }
现在很容易区分ivars
和getter/setter.访问者已获得self.
前缀.您不应该直接访问变量.
您的示例代码不能正常工作:
_myVar = some_other_object; // _myVar is the ivar, not myVar. self.myVar = some_other_object; // works too, uses the accessors
命名的合成属性prop
实际上由两个方法prop
(返回属性的当前值)和setProp:
(为prop设置新值)表示.
该self.prop
语法是调用这些访问的一个语法糖.在您的示例中,您可以执行以下任一操作来设置属性myVar
:
self.myVar = @"foo"; // handles retain/release as specified by your property declaration [self setMyVar: @"foo"]; // handle retain/release _myVar = @"Foo"; // does not release old object and does not retain the new object
要访问属性,请使用self.propname
.要访问实例变量,只需使用实例变量的名称.
使用@synthesize myVar = _myVar策略的问题是,我认为编写代码如:
myVar = some_other_object; // doesn't work.编译器抱怨
myVar
未申报.为什么会这样?
因为变量myVar
是未声明的.
该语句使用语法来访问变量,无论是实例变量还是其他类型.正如rincewind告诉你的那样,要访问属性,必须使用property-access语法(self.myVar = someOtherObject
)或显式消息来访问者方法([self setMyVar:someOtherObject]
).
否则,您正在尝试访问变量,并且由于您没有命名变量myVar
,因此您尝试访问不存在的变量.