我试图更深入地了解保留释放。这是我的代码,然后我将发布代码运行的输出。我不确定为什么当为'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
答案 0 :(得分:2)
系统的任何其他部分可能保留了您的号码和标签。有些东西可能会保留它并发送它autorelease
并且自动释放池可能尚未耗尽。您通常不应该假设某个对象的保留计数,除非它至少与您的代码负责的保留数量一样大。
特别是,视图会保留其所有子视图。这至少占标签保留计数的+1。
您的号码的保留计数为2,因为alloc
返回一个保留计数为1的对象,而您(我认为)将其存储在strong
或retain
属性中,增加其保留计数。您正在泄露此对象,因为您负责释放它(以平衡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
会被多个对象保留。
_label
ivar。编辑 - 如果您对ARC
持怀疑态度,请阅读此内容不可否认,我是ARC转换者。我确实理解手动引用计数(旧方法)。一旦我切换到ARC,我就没有回头。我不会在这里写一个很长的dia骂,但如果你是一个怀疑论者,这个链接值得一看。最后,如果您还没有准备好或有自己的理由想要使用MRC,那就去吧。这是我的意见,希望它有用。
http://www.learn-cocos2d.com/2012/06/mythbusting-8-reasons-arc/
答案 2 :(得分:0)