我只是想知道以下两种方法。
首先:
SomeViewController *someViewController = [[SomeViewController alloc] init];
[self.navigationController pushViewController:someViewController animated:YES];
[someViewController release];
第二
SomeViewController *someViewController = [[SomeViewController alloc] init];
self.iVarViewController = someViewController;
[someViewController release];
[self.navigationController pushViewController:self.iVarVierController animated:YES];
采取第一种方法是否可以,或者应该总是尝试采用第二种方法?第一种方法究竟出了什么问题?当'someViewController'被推入堆栈时,它的保留计数是否会增加,因此永远不会完全释放?这就是为什么你可能想像第二种方法那样将它分配给一个属性?但是在第二种方法中,你无法确定它何时会被释放。
我读过一个similar post,但我仍然有点不确定,所以以为我会问更简单。
答案 0 :(得分:1)
他们都没问题。将SomeViewController
推送到堆栈时,其保留计数会递增。当它从堆栈弹出时,其保留计数再次递减。之后您无需自己明确释放它。事实上,这可能会导致异常发生。
有一条简单的一般规则:无论何时拨打alloc/retain/new/copy*
,您都需要在某个时间拨打release
。
您在此处仅呼叫alloc
,因此您只需拨打release
一次。
编辑:在第二种方法中,您通过使用setter隐式调用retain
。因此,在这种情况下,稍后您需要额外的release
以防止内存泄漏。
答案 1 :(得分:0)
这两种方法的后果略有不同。在第一个实例中,SomeViewController
的实例及其视图将在弹出实例后立即释放。在第二个中,SomeViewController
的实例将保留在内存中,直到被新的实例替换为self.iVarViewController = someViewController
。
如果第一个视图控制器需要在弹出第二个控制器后向第二个视图控制器发送消息(例如获取更改的属性值),则第二种方法可能有意义。但在这种情况下,您必须问自己每次重新创建对象是否有意义,而不是仅仅重用存储在属性中的实例(在您的示例中为ivarViewController
)。
一个是否优于另一个取决于应用程序的这一部分的预期使用模式的组合,以及第二个控制器及其视图的性能特征。 (例如,对象消耗了多少内存,用户通常在两个控制器之间来回切换的频率是多少?)