了解内存管理

时间:2014-08-14 20:50:38

标签: ios objective-c memory-management retain

我尝试更好地理解Objective C中的内存管理(没有ARC)。 目前正在创建一个简单的程序来试用它。

我的代码

...
//create some object
RetainTracker * rt = [RetainTracker new]; //RC=1
NSLog(@"Just created - %lu", (unsigned long)[rt retainCount]);
[rt retain]; // RC=2
NSLog(@"%lu", (unsigned long)[rt retainCount]);
[rt release]; //RC=1
NSLog(@"%lu", (unsigned long)[rt retainCount]);
[rt release]; //RC=0 -> call to dealloc    
//call to object rt again after it was deallocated and get RC=1
NSLog(@"%lu", (unsigned long)[rt retainCount]); //think that here must be exception ?

结果:

enter image description here

因此,结果我们可以看到在我发布最后一个引用和对象rt之后引用计数器仍然等于1。

我更深入,并与仪器“生命”调查此对象,下一步

enter image description here

据我所知:

  • 第0步 - 只需创建 - RC = 1;
  • 第1步 - 代码[rt retain] - RC = 2;
  • 第3步 - 代码[rt release] - RC = 1;
  • 第4步 - 代码[rt release] - RC = 0;

所以,对象必须被释放,但是如果我在步骤4之后调用[rt retainCount],那么此对象的RC仍然等于1.为什么?也许我犯错了或错过了什么?

2 个答案:

答案 0 :(得分:3)

取消分配对象后,使用指向对象的指针会导致未定义的行为。也就是说,它可以打印1,42,你的程序可能会崩溃,Hello Kitty可能会弹出你的计算机;什么都可能发生。任何行为都与未定义的行为一致,即使是表明正在发生其他事情的行为也是如此。

除了它未定义的行为之外,你所看到的很可能是基于你所做的。取消分配对象后,其内存将标记为可供使用,但构成内存中对象的字节仍保留在那里。因此,在很长一段时间内,很可能它没有被其他东西覆盖,而且内存仍然会看起来"就像被解除分配的对象一样,向它发送消息(虽然未定义的行为)可能会成功,因为它只是使用对象的部分仍然在内存中的正确位置。

关于保留计数,你假设当你release时,保留计数(但它存储在内存中)总是递减,所以如果在release之前它是1,之后应该是0.但是,当保留计数为1时,他们不必这样做,因为他们知道当你release保留计数为1的对象时,对象将是取消分配,之后你不应该使用该对象,所以他们也可以在这种情况下跳过减少它,因为更新一个不再使用的变量没有意义。

答案 1 :(得分:0)

当池的保留计数为0时,对象将被释放。对象在释放后仍可能在内存中。尝试在下一次排水后访问它,看看会发生什么。

更新: 是。我的错。出于某种原因,我错过了它没有自动释放的事实。但是我正在查看retainCount方法,并在文档中找到了这个:"不要使用此方法。 (必需)"

并遵循:" ...您不太可能从此方法中获得有用的信息"。

似乎retainCount方法可能无法可靠地为您提供对象的保留计数。但是,仍然很奇怪你甚至可以将该消息发送到应该被释放的那个对象。