2013-04-08 24 views
-1

我试图更深入地了解保留版本。这是我的代码,然后我将发布代码运行的输出。我不确定为什么当dealloc被称为'self'时保留计数从不为零。在dealloc被调用之前,retainCount如何不为零?

二为什么self.testNumber的保留数为2的时候我的Alloc给它的内存,我应该使用的测试号的“弱”属性,而不是

CODE:

#import "ViewController.h" 

@interface ViewController() 

@end 

@implementation ViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
    _testNumber = [[NSNumber alloc] initWithInt:10]; 
    testNumber = [[NSNumber alloc] initWithInt:102]; 
    _testInt = 105; 
    self.testNumber = [[NSNumber alloc] initWithInt:101]; 
    NSLog(@"self.testNumber retain count = %d",[self.testNumber retainCount]); 
    NSLog(@"self.label retain count = %d",[self.label retainCount]); 

    self.label.text = [NSString stringWithFormat:@"%d %d %d",_testNumber.integerValue,self.testNumber.integerValue,testNumber.integerValue ]; 
    NSLog(@"self before release retain count = %d",[self retainCount]); 

    [self release]; 
    NSLog(@"self after release retain count = %d",[self retainCount]); 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

- (void)dealloc { 
    NSLog(@"_label after before retain count = %d",[_label retainCount]); 

    [_label release]; 
    NSLog(@"_label after release retain count = %d",[_label retainCount]); 


    [super dealloc]; 
} 

OUTPUT :

2013-04-08 15:31:28.503 propertiesTest[5561:907] self.testNumber retain count = 2 
2013-04-08 15:31:28.507 propertiesTest[5561:907] self.label retain count = 3 
2013-04-08 15:31:28.509 propertiesTest[5561:907] self before release retain count = 3 
2013-04-08 15:31:28.510 propertiesTest[5561:907] self after release retain count = 2 
2013-04-08 15:31:28.532 propertiesTest[5561:907] _label after before retain count = 3 
2013-04-08 15:31:28.534 propertiesTest[5561:907] _label after release retain count = 2 
+5

看到这个答案的理由不使用/依赖retainCount:http://stackoverflow.com/questions/6276442/why-retaincount-2-after-release – 2013-04-08 19:39:36

+0

怎么样的一部分,其中self.testNumber = [[NSNumber alloc] initWithInt:101];这种情况下的retainCount显示2应该是正确的。但是,我应该使用'弱'来代替分配吗?它正在做一个双重保留。 – mskw 2013-04-08 19:44:31

+0

请记住,例如,如果_label是您的视图的一部分,它将被视图保留。 – 2013-04-08 20:11:45

回答

2

任意数量的系统的其他部分可能会保留你的号码和标签的东西可能保留它,把它autorelease和AUTORE。租赁池可能尚未排干。通常不应该对对象的保留计数作出假设,除非它至少与代码负责的保留数量一样大。

特别是,视图保留了它的所有子视图。这占标签保留计数的至少+1。

您的号码有两个原因alloc返回一个对象以1:1的保留计数一个保留计数,而你(我相信)其存储在strongretain属性,增加其保留计数。您正在泄漏此对象,因为您有责任释放它(以平衡由alloc执行的保留),并且您没有这样做。你应该重写它是这样的:

self.testNumber = [[[NSNumber alloc] initWithInt:101] autorelease]; 

或像这样:

self.testNumber = [[NSNumber alloc] initWithInt:101]; 
[self.testNumber release]; 

或像这样:

self.testNumber = [NSNumber numberWithInt:101]; 

,或者最重要的,打开ARC,让编译器负责释放它。

请注意,你不需要看保留计数来诊断这个问题!只要运行静态分析器(选择从Xcode的产品菜单中分析)就会显示泄漏。或者你可以通过学习和理解Cocoa内存管理约定来诊断它(这是我所做的)。阅读Advanced Memory Management Programming Guide。这并不是那么先进。

如果您想了解您的号码或标签保留和发布的位置,最好的方法是使用分配工具。详情请参阅this answer。也是this answer

+0

这是一个重复,但我想知道这个:self.testNumber = [[NSNumber alloc] initWithInt:101 ]。这种情况下的retainCount显示2应该是正确的。但是,我应该使用'弱'来代替分配吗?它正在做一个双重保留。 – mskw 2013-04-08 20:23:19

+1

您需要停止担心保留计数。 “弱”是什么意思?属性的'weak'属性只有在启用ARC的情况下才有效,并且已禁用ARC。如果你想保证'NSNumber'实例处于这个状态,你需要保留它(你将它分配给'strong'或'retain'属性)。 – 2013-04-08 20:59:11

+0

我已经更新了我的答案。 – 2013-04-08 21:44:22

1

从obj-c编码的角度来看,我不会挂在保留计数上。我会考虑使用ARC(强烈建议恕我直言,将帮助您编写可维护,清晰的代码并消除常见的内存管理错误)。

根据您的具体问题,_label由多个对象保留。

  1. 你的控制器保留在_label伊娃。
  2. 它的父被其保留
  3. 取决于你的代码,它可以在其他地方保留

编辑 - 如果你怀疑ARC

不可否认看了这个,我是一个ARC转换。我明白手动引用计数(旧方法)。一旦我切换到ARC,我还没有回头。我不打算在这里写一个长篇谩骂,但如果你是一个怀疑论者,这个链接值得一看。最后,如果你还没有准备好或有自己想要使用MRC的理由,那就去做吧。这是我的看法,希望它有用。

http://www.learn-cocos2d.com/2012/06/mythbusting-8-reasons-arc/

+0

哦,干净的代码和消除常见的MM错误与ARC没有任何关系,它关乎编程风格和理解原则。我看到程序员用ARC做了可怕的事情,错误几乎看不见,因为没有明确的“保留”或“释放”。较短的代码是,但没有更清晰或更明显。有时候使用ARC只是很痛苦(例如块)。 – Sulthan 2013-04-08 20:01:25

+1

给他自己。对于糟糕的编码,ARC不是一个神奇的项目。那不是我的意思。 ARC消除了不必担心保留和释放语义的负担。我不同意ARC在使用块时很痛苦。除非你明确地不希望它们,否则块会自动在其中保留引用。 – XJones 2013-04-08 20:31:35

相关问题