我总是在 viewDidLoad 方法中看到示例代码,而不是说,例如
someInstanceVar = [[Classname alloc] init];
他们总是去
Classname *tempVar = [[Classname alloc] init];
someInstanceVar = tempVar;
[tempVar release];
为什么是这样?不是完全一样,只是更长吗?
我总是在 viewDidLoad 方法中看到示例代码,而不是说,例如
someInstanceVar = [[Classname alloc] init];
他们总是去
Classname *tempVar = [[Classname alloc] init];
someInstanceVar = tempVar;
[tempVar release];
为什么是这样?不是完全一样,只是更长吗?
简短的回答:这种模式一直出现在 iPhone 代码中,因为它被认为是创建新对象并将其分配给成员变量的最佳方式,同时仍然尊重所有内存管理规则并调用适当的副作用(如果任何)同时也避免使用自动释放。
细节:
您的第二个示例将创建一个僵尸,因为var
它持有一个指向已释放内存的指针。一个更可能的用例如下所示:
tempVar = [[Classname alloc] init];
self.propertyVar = tempVar;
[tempVar release];
假设这propertyVar
是一个声明为copy
或retain
属性,此代码将新对象的所有权移交给该类。
更新 1:以下代码是等效的,但在 iOS 上不推荐*,这可能是大多数 iPhone 程序使用第一种模式的原因。
self.propertyVar = [[[Classname alloc] init] autorelease];
*
在 iOS 上不鼓励使用autorelease ,因为过度使用它会导致问题。确保您永远不会过度使用它的最简单方法是永远不要全部使用它,因此您会经常看到使用alloc/init
and的 iOS 代码release
,即使在autorelease
可以接受的情况下也是如此。这是编码器偏好的问题。
更新 2:由于 Cocoa 在幕后自动执行的内存管理,这种模式起初看起来令人困惑。这一切的关键是用于设置成员变量的点表示法。为了帮助说明,请考虑以下两行代码是相同的:
self.propertyVar = value;
[self setPropertyVar:value];
当您使用点表示法时,Cocoa 将为指定的成员变量调用属性访问器。如果该属性被定义为copy
orretain
属性(这是该模式在不创建僵尸的情况下工作的唯一方法),那么会发生几件非常重要的事情:
propertyVar
释放