Objective-c中的对象创建和实例化

时间:2011-07-06 12:24:59

标签: objective-c memory-management

给出下面的代码,其中blueViewController是一个iVar 问题:为什么不直接实例化iVar?

BlueViewController *blueController = [[BlueViewController alloc]initWithNibName:@"BlueView" bundle:nil];
self.blueViewController = blueController;
[blueController release];

4 个答案:

答案 0 :(得分:2)

您可以直接初始化iVar,但您所拥有的代码也会处理以前的blueViewController值的内存管理。直接访问iVar,您必须在分配新值之前手动释放以前的值。

答案 1 :(得分:2)

这取决于你班上的位置。如果您使用的是init(和dealloc)方法,建议直接引用ivar以避免在setter逻辑中出现任何副作用。因此在init中我会做

_blueViewController = [[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil];

但是在其他任何地方我都会这样做你怎么做的。然后,如果getter / setter中有任何自定义逻辑,我知道它将被运行。

要详细说明@ Vladimar的观点,保留的合成setter将执行类似于此的一些内存管理:

- (void)setMyObject:(MyObject *)newMyObject
{
  // If it's the same object we don't need to do anything
  if (_myObject != newMyObject) {
    [newMyObject retain];
    [_myObject release];
    _myObject = newMyObject;
  }
}

当你设置你的ivars时,让getter / setter担心所有这些逻辑会更安全。

答案 2 :(得分:1)

如果需要,您可以在一行中完成所有操作。重要的是平衡+ alloc与-release或-autorelease。所以,你可以说:

self.blueViewController = [[[BlueViewController alloc] initWithNibName:@"BlueView" bundle:nil] autorelease];

这很好,但是有些人更喜欢避免-autorelease,而有些人更喜欢简单的步骤和/或更短的代码行。在这方面使用中间变量有助于这方面,而且不需要任何费用。

答案 3 :(得分:1)

取决于属性是否为retain。保留了大多数对象属性;这就是保留属性的样子:

- (void)setBlueViewController:(BlueViewController *)bvc {
    if (bvc != blueViewController) {    // blueViewController is local ivar
        [blueViewController release];
        blueViewController = [bvc retain];
    }
}

所以你在那里做的是创建一个+2的保留计数。当你init时,那是+1;该属性然后retain s,将其提升到+2。你的dealloc发布一次,将其降低到+1 ......你就泄露了这个属性。因为你是变量的alloc / init,所以你不想使用setter;相反,将其直接分配给实例变量。

通过直接实例化,可以省去其他release的麻烦 - 更少的代码行意味着更少的错误。例如,您可能偶然输入了retain并且在您的程序崩溃之前没有实现它,因为您保留了一个庞大的类......

当然,正如Caleb所说,你可以自动释放,但这有效地让对象在内存中存在,直到运行循环结束。它更容易,并为您提供更多控制,只是不用担心。将alloc / init分配给ivar并没有错;事实上,这是最好的方法。