为什么人们总是在Objective-C(即iPhone)中使用重新分配实例变量?

Mar*_*rty 10 iphone coding-style objective-c instance-variables

我总是在viewDidLoad方法中看到示例代码,而不是说,例如

someInstanceVar = [[Classname alloc] init];
Run Code Online (Sandbox Code Playgroud)

他们总是去

Classname *tempVar = [[Classname alloc] init];
someInstanceVar = tempVar;
[tempVar release];
Run Code Online (Sandbox Code Playgroud)

为什么是这样?是不是完全一样,只是更长?

e.J*_*mes 12

简短的回答:这种模式一直出现在iPhone代码中,因为它被认为是创建新对象并将其分配给成员变量的最佳方式,同时仍然尊重所有内存管理规则并调用适当的副作用(如果任何)同时也避免使用自动释放.

细节:

你的第二个例子会创建一个僵尸,因为var它留下了一个指向已经释放的内存的指针.更可能的用例如下所示:

tempVar = [[Classname alloc] init];
self.propertyVar = tempVar;
[tempVar release];
Run Code Online (Sandbox Code Playgroud)

假设它propertyVar是声明为copyretain属性,此代码将新对象的所有权移交给类.

更新1:以下代码是相同的,但不推荐*在iOS上,这可能是大多数iPhone程序使用第一个模式的原因.

self.propertyVar = [[[Classname alloc] init] autorelease];
Run Code Online (Sandbox Code Playgroud)

*在iOS 上不鼓励自动释放,因为它可能在过度使用时导致问题.最简单的方法,以确保你永远不会滥用它是从来没有使用它,所以你会经常看到,使用iOS的代码alloc/initrelease,即使autorelease是可以接受的.这是编码器偏好的问题.

更新2:这个模式起初看起来很混乱,因为Cocoa在后台自动执行内存管理.这一切的关键是用于设置成员变量的点符号.为了帮助说明,请考虑以下两行代码是相同的:

self.propertyVar = value;
[self setPropertyVar:value];
Run Code Online (Sandbox Code Playgroud)

当您使用点表示法时,Cocoa将调用指定成员变量的属性访问器.如果该属性已被定义为copyretain属性(这是此模式在不创建僵尸的情况下工作的唯一方式),则会发生以下几个非常重要的事情:

  1. 无论以前存储的propertyVar是什么值都会被释放
  2. 保留或复制新值
  3. 任何副作用(例如KVC/KVO通知)都会自动处理

  • `instanceVar = value`和`this.instanceVar = value`之间存在一个关键区别.使用点表示法告诉编译器调用属性访问器,它在后台自动处理内存管理. (3认同)
  • 当然你的意思是"自我"而不是"这个"? (2认同)