1

这是 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

Q3:为什么?

显然,我在 alloc/init/release 周期(Q 的 1 和 2)以及假定的newalloc/init(Q3)的等效性中遗漏了一些概念性的东西。任何人都可以向我指出一个教程,它可以像我一样为难以思考的人解释更多的东西吗?

谢谢,

账单

4

2 回答 2

5

你有没有机会覆盖+new你的班级?它应该做与+alloc/-init.

无论如何,你的第一行

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

正在泄漏您的TheShape实例。你应该把它变成

[arrayOfObjects addObject:[[[TheShape alloc] init] autorelease]];
于 2011-01-25T01:44:32.360 回答
1

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

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

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

  • 你调用retain对象;
  • 您通过调用copymutableCopy在另一个对象上获得一个对象;
  • 您在对象上调用该alloc方法。

每当您拥有一个对象时,您就有责任在不再需要它时释放它。只有在没有人需要它时才会删除它。

在您的代码段中,创建传递给数组的对象。您的数组开始使用它,因此它会调用retain它(因此它在被持有时保持活动状态)。但是,一旦您release获得了数组,您的对象仍然需要由释放,因为您调用了该alloc方法。


编辑简单的片段:

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

不过,应该显示消息。:/

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

  • alloc您对,init或方法做了一些奇怪的事情release(在这种情况下,发布您的代码);
  • 您在垃圾收集环境中运行,并且dealloc永远不会被调用(finalize在这种情况下您应该使用它)。虽然我不明白为什么+newthenrelease会给出预期的结果。
于 2011-01-25T01:47:16.883 回答