在调用dealloc之前,retainCount怎么不为零?

时间:2013-04-08 19:33:40

标签: ios objective-c

我试图更深入地了解保留释放。这是我的代码,然后我将发布代码运行的输出。我不确定为什么当为'self'调用dealloc时,保留计数永远不会为零。

为什么self.testNumber的保留计数是2,当我为它分配内存时,我应该使用'弱'属性代替测试号吗?

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];
}

输出:

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

3 个答案:

答案 0 :(得分:2)

系统的任何其他部分可能保留了您的号码和标签。有些东西可能会保留它并发送它autorelease并且自动释放池可能尚未耗尽。您通常不应该假设某个对象的保留计数,除非它至少与您的代码负责的保留数量一样大。

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

您的号码的保留计数为2,因为alloc返回一个保留计数为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&Product产品菜单中选择Analyze)即可显示泄漏情况。或者你可以通过学习和理解Cocoa内存管理约定来诊断它(这就是我所做的)。阅读Advanced Memory Management Programming Guide。它并不是那么先进。

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

答案 1 :(得分:1)

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

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

  1. 您的控制器将其保留在_label ivar。
  2. 其超级视图保留它
  3. 取决于您的代码,可以保留在别处
  4. 编辑 - 如果您对ARC

    持怀疑态度,请阅读此内容

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

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

答案 2 :(得分:0)

递减retainCount然后立即转身并取消分配对象会有什么意义?

请记住,retainCount 永远不会返回零

BTW:http://www.whentouseretaincount.com/

相关问题