-当拥有数组 dealloc 时,不会调用 dealloc 方法...应该吗?
以下是 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...”字符串出现在日志中。事实并非如此。
问题一:为什么不呢?
所以我深入挖掘并简化了事情。如果我做这样更简单的事情:
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)中遗漏了一些概念性的东西。有人能给我指点一个教程,可以为像我这样的困难思维者提供更多解释吗?
谢谢,
比尔
Here are two pieces of Objective-C code in a Foundation app. This piece of code is in a function:
[arrayOfObjects addObject:[[TheShape alloc] init]];
NSLog(@"%@", arrayOfObjects); // log verifies "<TheShape..." is in the array
[arrayOfObjects release];
and in my TheShape class, I have this dealloc
override method:
- (void)dealloc {
NSLog(@"TheShape dealloc called.");
[super dealloc];
}
Although my program works otherwise, it doesn't work the way I expect it to. When the [arrayOfObjects release]
message is sent, I expect to see the "TheShape dealloc..." string appear in the log. It doesn't.
Q1: Why not?
So I dig a bit and simplify things. If I do something simpler like this:
TheShape *aShape = [[TheShape alloc] init];
[aShape release];
the debug message still doesn't appear in the log.
Q2: Why not?
But if I do this:
TheShape *aShape = [TheShape new];
[aShape release];
the debug message does appear in the log. The debug message also appears in the log if I change the alloc/init in the first sample to new
, too.
Q3: Why?
Obviously, I'm missing something conceptual in the alloc/init/release cycle (Q's 1 and 2) and in the supposed equivalency of new
and alloc/init
(Q3). Can anybody point me to a tutorial that explains things a bit more for the hard of thinking, like me?
Thanks,
Bill
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否有机会在您的课程上覆盖
+new
?它应该做与 +alloc/-init 完全相同的事情。无论如何,您的第一行
正在泄漏您的
TheShape
实例。你应该把它变成By any chance did you override
+new
on your class? It should be doing precisely the same thing as+alloc/-init
.In any case, your very first line
is leaking your
TheShape
instance. You should turn that in to没有理由调用
dealloc
方法:您的对象仍然具有非零引用计数。每当创建一个对象时,它的引用计数都是从 1 开始的。一旦该计数达到 0,它就会被释放。内存管理有一些特定的规则可以帮助我们保持理智。这些规则谈到“对象所有权”。
基本上,如果您满足以下条件之一,您就成为对象的所有者:
retain
;copy
或mutableCopy
来获取一个对象;alloc
方法。每当您拥有一个对象时,您有责任在不再需要它时释放它。只有当不再有人需要时才会将其删除。
在您的代码片段中,您创建了传递给数组的对象。您的数组开始使用它,因此它对其调用
retain
(因此它在被保留时保持活动状态)。但是,一旦您释放
数组,您的对象仍然需要由您释放,因为您调用了alloc
方法。编辑 简单的片段:
不过应该显示消息。 :/
我认为这种情况没有发生有两个原因:
alloc
、init
或release
方法做了一些奇怪的事情(其中案例,发布您的代码);+new
thenrelease
会给出预期的结果。There's no reason for the
dealloc
method to be called: your object still has a non-zero reference count.Whenever you create an object, it begins its existence with a reference count of 1. Once this count reaches 0, it is deallocated. There are specific rules for memory management that help us all stay sane. These rules speak of 'object ownership'.
Basically, you become the owner of an object if you meet one of these conditions:
retain
on the object;copy
ormutableCopy
on another one;alloc
method on an objet.Whenever you own an object, you are responsible for releasing once you don't need it anymore. It will be deleted only once no one needs it anymore.
In your snippet, you create the object that you pass to your array. Your array begins to use it, so it calls
retain
on it (so it stays alive while it's being held). However, once yourelease
the array, your object still needs to be release by you, since you called thealloc
method.EDIT The simple snippet:
should show the message, though. :/
There are two reasons I can see this not happening:
alloc
,init
orrelease
method (in which case, post your code);dealloc
will simply never be called (it'sfinalize
you should use in this case). Though I don't see why+new
thenrelease
would give the expected results then.