为什么要以环形方式初始化将成为属性的对象?

时间:2009-07-31 21:54:34

标签: iphone objective-c

在三行中有什么理由可以在一行中完成?

以下是developer.apple.com的一些代码:

UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];

self.navigationController = aNavigationController;

[aNavigationController release];

......在同一行中也是如此:

self.navigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];

看起来干净,简单,直截了当。我以前遇到过一个没有被保留的属性的问题,导致[对象释放]在不应该的时候销毁对象(据我所知 - 保留属性已经设置)。使用单行公式就像花花公子一样。

3 个答案:

答案 0 :(得分:6)

Objective-C memory management rules规定通过alloc一个对象实例,你是一个(共享一次其他对象retain它)该实例的所有者,所以你必须{{1}当你想放弃所有权以防止内存泄漏时,release。在非垃圾收集环境中(例如在iPhone上),这意味着平衡UINavigationControlleralloc(或包含“alloc”或“copy”的方法)与copy或{{1 }}。那么你的第二个片段就是

release

如果您可以避免在内存有限的环境(如iPhone)上使用autorelease,最好使用显式self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease]; autorelease将接收器添加到当前release,随后将在某个时间内在池中的对象上调用-[NSObject autorelease]。当你想要小心内存使用时,“未来的某个时间”并不是一个好主意。因此,在iPhone上你的第一个例子是标准用法。

答案 1 :(得分:0)

Objective-C对象类型的大多数属性应在声明中声明为retain或copy。例如,您可能会说:

@property (retain) UINavigationController * navigationController;

如果是这种情况,自动编写的setNavigationController函数将为您调用retain,并且单行将为:

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];

如果您设置的属性使用(分配)而不是(保留)或(复制),则可能会遇到问题。在这种情况下,setter只使其指针等于另一个指针,然后释放该对象将导致它被清理。

如果您正在调用release而不是autorelease,则可能会遇到问题。

希望有所帮助!

答案 2 :(得分:0)

根据您在属性中的定义,您会发生内存泄漏。几乎每当你看到一个alloc / init组合,你就会得到一个引用计数为1的对象。假设您的属性被定义为retain(它可能应该是),那么设置该属性会将引用计数增加到两个。

如果你真的想把它全部保留在一行,请使用以下内容:

self.navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];

虽然建议不要这样做,因为自动释放的对象会导致它们的存在时间超过所需的时间。