在Xcode中我有一个UINavigationController,我推了一个UIViewController。
在那个UIViewController中我初始化一个UIScrollView。
一切都很好。
然而,在切换到另一个视图后,我记录了控制器的保留计数,令我惊讶的是它是一个而不是零。
以下是代码:
scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[self.view addSubview:scroller];
和
- (void)dealloc {
[super dealloc];
NSLog(@"retaincount, %d", [scroller retainCount]); //displays 2
[scroller release];
NSLog(@"retaincount, %d", [scroller retainCount]); // displays 1
}
我只启动它并将其添加到UIViewControllers视图。
亲切的问候,
汤姆
答案 0 :(得分:4)
不要使用retainCount!来自apple documentation:
重要:此方法在调试内存管理问题时通常没有价值。因为任何数量的框架对象可能保留了一个对象以保存对它的引用,而同时自动释放池可能在对象上保留任意数量的延迟版本,所以您不太可能从此获取有用信息方法。
要了解您必须遵守的内存管理的基本规则,请阅读“Memory Management Rules”。要诊断内存管理问题,请使用合适的工具:
- 即使在运行程序之前,LLVM/Clang Static analyzer通常也会发现内存管理问题。
- Instruments应用程序中的Object Alloc仪器(请参阅Instruments User Guide)可以跟踪对象分配和销毁。
- Shark(请参阅Shark User Guide)还介绍了内存分配(在程序的众多其他方面)。
话虽如此:您必须在[super dealloc]
方法的最后一行调用dealloc
。除此之外,代码中的所有内容都应该没问题。不要尝试手动降低retainCount。使用适当的内存管理。再说一遍,不要看看retainCount。
释放后不允许使用对象。如果由于您的释放而将释放滚动条,则第二个NSLog将导致BAD_ACCESS
异常。
答案 1 :(得分:1)
这就是原因:
scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
//retain count = 1
[self.view addSubview:scroller];
//retain count + 1 + 1 = 3
//later the AutoreleasePool decrements the count by 1, resulting in a retain count of 2.
init…
开头的方法
返回非自动释放的实例
保留计数为1。self.view:
返回一个自动释放的保留指向子视图的指针。addSubview:
retains the
subview。removeFromSuperview:
releases it 您不应该依赖对象的保留计数。
相反,您必须注意保持和释放对象的调用
请务必在此问题上阅读Apple的Memory Management Programming Guide! (特别是rules section!)
答案 2 :(得分:1)
self.view
正在保留它。当您的UIViewController deallocs时,它将释放self.view
,它将释放所有保留的子视图。实际上,您可能应该在将其添加到self.view
之后立即将其发布。
那就是说,我强烈第二个@ fluchtpunkt的回答。检查retainCount
属性以查找调试信息只会导致Stack Overflow上的混乱和日益连贯的帖子。
答案 3 :(得分:1)
以前的答案是正确的:不要使用-retainCount,并确保在自己的-dealloc实现中最后调用[super dealloc]
。
我想补充一点,你可能永远不会看到一个案例(不是你应该看的),其中-retainCount返回0.如果一个对象的retainCount降为零,则该对象被释放。实际上,似乎Cocoa甚至都没有把retainCount设置为零...如果之前的retainCount为1,则释放似乎解除对象。还有一个理由认为-retainCount是私有实现细节。