拥有数组dealloc'd时没有调用-dealloc方法......应该吗?

时间:2011-01-25 01:40:40

标签: objective-c release new-operator init alloc

以下是Foundation应用程序中的两段Objective-C代码。这段代码在一个函数中:

    [arrayOfObjects addObject:[[TheShape alloc] init]];
    NSLog(@"%@", arrayOfObjects); // log verifies "<TheShape..." is in the array
    [arrayOfObjects release];

在我的TheShape课程中,我有这个dealloc覆盖方法:

    - (void)dealloc {
        NSLog(@"TheShape dealloc called.");
        [super dealloc];
    }

虽然我的程序不起作用,但它并不像我期望的那样工作。发送[arrayOfObjects release]消息时,我希望看到“TheShape dealloc ...”字符串出现在日志中。它没有。

Q1:为什么不呢?

所以我稍微挖掘一下并简化一些事情。如果我做一些更简单的事情:

    TheShape *aShape = [[TheShape alloc] init];
    [aShape release];

调试消息仍然没有出现在日志中。

Q2:为什么不呢?

但如果我这样做:

    TheShape *aShape = [TheShape new];
    [aShape release];

调试消息 出现在日志中。如果我将第一个样本中的alloc / init更改为new,则调试消息也会出现在日志中。

问题3:为什么?

显然,我在alloc / init / release周期(Q的1和2)以及newalloc/init(Q3)的假定等价中缺少一些概念。任何人都可以指点我一个教程,解释一些难以思考的事情,比如我吗?

谢谢,

比尔

3 个答案:

答案 0 :(得分:5)

你有没有机会在课堂上覆盖+new?它应该与+alloc/-init完全相同。

无论如何,你的第一行

[arrayOfObjects addObject:[[TheShape alloc] init]];

正在泄露您的TheShape个实例。你应该把它转到

[arrayOfObjects addObject:[[[TheShape alloc] init] autorelease]];

答案 1 :(得分:1)

没有理由调用dealloc方法:您的对象仍然具有非零引用计数。

每当您创建一个对象时,它就会以引用计数为1开始存在。一旦该计数达到0,它就会被释放。内存管理有一些特定的规则可以帮助我们保持理智。这些规则涉及“对象所有权”。

基本上,如果您满足以下条件之一,您将成为对象的所有者:

  • 您在对象上调用retain;
  • 通过在另一个上调用copymutableCopy来获取对象;
  • 您可以在对象上调用alloc方法。

每当你拥有一个物体时,你有责任在你不再需要它时释放。只有在没有人需要它时才会被删除。

在您的代码段中,创建传递给数组的对象。你的数组开始使用它,所以它在它上面调用retain(所以它在被保持时保持活着)。但是,一旦你release数组,你的对象仍然需要由发布,因为你调用了alloc方法。


编辑简单摘要:

TheShape *aShape = [[TheShape alloc] init];
[aShape release];
但是,

应该显示消息。 :/

有两个原因我可以看到这种情况没有发生:

  • 您使用allocinitrelease方法做了一些奇怪的事情(在这种情况下,发布您的代码);
  • 您在垃圾收集环境中运行,dealloc将永远不会被调用(在这种情况下,您应该使用finalize)。虽然我不明白为什么+new然后release会给出预期的结果。

答案 2 :(得分:1)

这个Link提供了有关内存管理的有用信息。