2

也许是一个愚蠢的问题,但我想我还是会问这个问题,因为我仍在努力解决内存管理问题。

这是 :

1.

ViewController *tViewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
self.viewController = tViewController;
[tViewController release];

比这更好:

2.

self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease];

如何以及为什么?

编辑:

好的,首先,我已经安全地释放了我所拥有的一切。我可以看到这种情况发生。

但是在第二种情况下,它是一个延迟发布,那么我如何确定它什么时候消失呢?这autorelease东西有点让我困惑。

这不是程序中可能发生此类事情的唯一实例。当我想让我创建的特定对象保持活力直到天知道什么时候,我该怎么办?我autorelease呢?但如果它在错误的时间消失了呢?那我该怎么办?

4

4 回答 4

3

两者的最终结果是相同的,但他们到达那里的方式不同。在这两种情况下,您都在创建一个稍后发布的临时引用。

第一个版本在发布时立即释放实例(确定性)——尽管由于 self.viewController 可能是一个强引用,实例不会在发布调用时被释放。

当当前自动释放池被释放时,第二个版本会在未来某个时间点(非确定性)释放实例。再一次 - 如果 self.viewController 持有对它的引用,则不会被释放。

于 2013-06-13T14:01:49.683 回答
1

两者都是一样的。唯一的区别是 1 有一个 reference[tViewController] 来设置实例,而在 2 中它是直接完成的。

于 2013-06-13T13:46:08.440 回答
0

问题是,在第一种情况下,您确实手动释放 viewController。它立即销毁。在第二种情况下,对象在事件循环结束时被销毁。有时,如果我在一个包含大量自动释放对象的函数中循环执行一些消耗内存的操作 - 我会手动创建自动释放池并在每次迭代时将其耗尽。

来自 NSAutoreleasePool 类参考:

Application Kit 在事件循环的每个循环开始时在主线程上创建一个自动释放池,并在结束时将其排出,从而释放在处理事件时生成的任何自动释放对象。

于 2013-06-13T14:04:11.857 回答
0

我总是在我的书中说,第二种方式更好。但在过去,有些人不同意,尤其是。在 iOS 上。有什么不同?

  1. 有什么区别吗?

两种变体都分配一个对象。两种变体都负责发布它。(“自动释放是一种释放。”)但他们在不同的时间点这样做:

  1. Variant:对象在 ARP 结束时释放,至少在 runloop 结束时。
  2. 变体 2:对象立即被释放release

(两者:如果没有额外的参考。)

  1. 为什么我需要-autorelease?

在某些情况下,release如果不违反 MM 规则,a 是不可能的。最简单的情况是您想要返回一个分配的对象。谁应该释放它?创建方法?这将返回一些可能被释放的东西。发送消息的方法?这会使 +1 方法alloc与 -1 方法(如release. 没有出路。

例子:

- (NSString*)fullName
{
   NSString *fullName = [[NSString alloc] initWithFormat:@"%@, %@", self.lastName, self.firstName];
   return fullName; // Who balance +alloc?
}

通过自动释放对象,您的方法保持平衡并可以安全地返回对象。

在其他情况下,这是摆脱依赖关系的便捷方式。想象一下这段代码:

Person *person = …;
NSString *name = person.name;
[person release], person=nil; // Imagine that this will dealloc the instance.
// name is invalid, because person released it.

有了autorelease你就没有这个问题了。有几种解决方案:

getter 将retain,发送autorelease到返回值。ARP 中还有一个额外的引用来防止字符串被解除分配:

- (NSString*)name
{ return [[_name retain] autorelease]; }

或者使用该方法的人这样做:

NSString *name = [[person.name retain] autorelease];

问题的下一个问题release是,它更难使用returnbreak或者continue

while (…)
{
    id object = [[Class alloc] …]
    if (…)
    {
       break;
    }
    [object release];
}

自动释放没有问题。

Next: 出于某些原因,使用便利分配器(如果存在)是个好主意。从那里返回的对象不允许显式释放,因此放弃引用的代码依赖于如何设置引用。为什么不一直使用自动释放?

  1. 自动释放的缺点是什么

对象删除可能会延迟,因此您可能会遇到内存占用问题。但我个人认为,@autorelease{}这比release.

于 2013-06-13T14:13:25.373 回答