Objective-C: _variable
好吧,这肯定是以前问过的,但我看起来很生气,什么也没发现:
我的iPhone应用程序中有一个简单的数组,我定义如下:
1 2 | @property (nonatomic, strong) NSArray *pages; @synthesize pages = _pages; |
我在Apples示例代码中看到了这一点,并认为这是编写self.pages(即,使用页面替换self.pages)的一个很好的捷径,如下所示:
1 | _pages = [[NSArray alloc] init]; |
但苹果又有了这个(不完全是这样,但看起来好像他们一直在随机交换):
1 | self.pages = [NSKeyedUnarchiver unarchiveObjectWithData:contents]; |
最后:
1 | [_pages release]; |
这让我很困惑。页面和self.pages有什么区别?
谢谢你的帮助。
您将在初始值设定项和dealloc方法中通过
这种差异来自于常见的命名和使用实践。
实例变量和属性都引用同一对象。命名差异用于指出ivar(
ivar由类的实例拥有,由它们来处理它的所有权操作(alloc、retain、release等)。通常,这些所有权操作发生在
另一方面,该属性为IVAR提供"指定"访问点。属性方法(setter和getter)可以执行适当管理ivar所需的其他操作。因此,不建议直接访问ivar(作为一种使用模式),即使在拥有的对象中也是如此。例如,可以这样实现setter:
1 2 3 4 5 6 7 8 9 | - (void) setPages:(NSArray *)newValue { [newValue retain]; // additional operations that you will miss if you use the ivar [someObject someUsefulOperationThatIsReallyNeeded]; [pages release]; _pages = newValue; } |
当您使用简单的分配时:
页=…
只需设置实例变量。
使用财产转让时:
self.pages=…
它调用由编译器自动合成的方法(或由您定义的方法),为了合成此方法,它检查属性的类型(retain、assign,…)并编写与此类型属性匹配的代码。
因此,唯一实际的对象是实例变量
实际上,属性和合成器代码给出的代码与此代码相同(实际上,内存管理和线程锁定可能需要额外的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | @interface MyClass { ... NSArray *_pages } - (NSArray*)pages; - (void)setPages:(NSArray*)newValue; @end @implementation MyClass - (NSArray*)pages { return _pages; } - (void)setPages:(NSArray*)newValue { _pages = newValue; // Note in non ARC code there would be some memort managment here } @end |
您可以将
当您引用为
将已保留的值(如alloc/init中的一个)分配给属性时,将该值分配给
使用前导"uu"作为实例变量也是一个属性,这是保持这两个变量分开的简单约定,并且避免在您指另一个变量时意外引用一个变量(通过错误地添加/删除