以下是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)以及new
和alloc/init
(Q3)的假定等价中缺少一些概念。任何人都可以指点我一个教程,解释一些难以思考的事情,比如我吗?
谢谢,
比尔
答案 0 :(得分:5)
你有没有机会在课堂上覆盖+new
?它应该与+alloc/-init
完全相同。
无论如何,你的第一行
[arrayOfObjects addObject:[[TheShape alloc] init]];
正在泄露您的TheShape
个实例。你应该把它转到
[arrayOfObjects addObject:[[[TheShape alloc] init] autorelease]];
答案 1 :(得分:1)
没有理由调用dealloc
方法:您的对象仍然具有非零引用计数。
每当您创建一个对象时,它就会以引用计数为1开始存在。一旦该计数达到0,它就会被释放。内存管理有一些特定的规则可以帮助我们保持理智。这些规则涉及“对象所有权”。
基本上,如果您满足以下条件之一,您将成为对象的所有者:
retain
; copy
或mutableCopy
来获取对象; alloc
方法。 每当你拥有一个物体时,你有责任在你不再需要它时释放。只有在没有人需要它时才会被删除。
在您的代码段中,您创建传递给数组的对象。你的数组开始使用它,所以它在它上面调用retain
(所以它在被保持时保持活着)。但是,一旦你release
数组,你的对象仍然需要由你发布,因为你调用了alloc
方法。
编辑简单摘要:
TheShape *aShape = [[TheShape alloc] init];
[aShape release];
但是,应该显示消息。 :/
有两个原因我可以看到这种情况没有发生:
alloc
,init
或release
方法做了一些奇怪的事情(在这种情况下,发布您的代码); dealloc
将永远不会被调用(在这种情况下,您应该使用finalize
)。虽然我不明白为什么+new
然后release
会给出预期的结果。答案 2 :(得分:1)
这个Link提供了有关内存管理的有用信息。