简体   繁体   English

Objective-C保留问题

[英]Objective-C retain question

In Xcode I have a UINavigationController on wichh I push a UIViewController. 在Xcode中,我在按下UIViewController时有一个UINavigationController。

In that UIViewController I init an UIScrollView. 在该UIViewController中,我初始化一个UIScrollView。

All good. 都好。

However, after switching to another view I log the retain count of the controller and to my surprise it's one instead of zero. 但是,切换到另一个视图后,我记录了控制器的保留计数,但令我惊讶的是,它是1而不是0。

Here's the code: 这是代码:

scroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];

[self.view addSubview:scroller];

and: 和:

- (void)dealloc {
    [super dealloc];

    NSLog(@"retaincount, %d", [scroller retainCount]);  //displays 2

    [scroller release];

    NSLog(@"retaincount, %d", [scroller retainCount]); // displays 1
}

I only init it ones and add it to the UIViewControllers view. 我只将其初始化并将其添加到UIViewControllers视图。

Kind regards, 亲切的问候,

Tom 汤姆

Do not use retainCount! 不要使用retainCount! From the apple documentation : 苹果文档

Important : This method is typically of no value in debugging memory management issues. 重要说明 :在调试内存管理问题时,此方法通常没有任何价值。 Because any number of framework objects may have retained an object in order to hold references to it, while at the same time autorelease pools may be holding any number of deferred releases on an object, it is very unlikely that you can get useful information from this method. 由于可能有许多框架对象保留了一个对象以保留对其的引用,而同时自动释放池可能会在一个对象上保留任何数量的延迟发布,因此从此获取有用信息的可能性很小方法。

To understand the fundamental rules of memory management that you must abide by, read “ Memory Management Rules ”. 要了解必须遵守的内存管理基本规则,请阅读“ 内存管理规则 ”。 To diagnose memory management problems, use a suitable tool: 要诊断内存管理问题,请使用合适的工具:

  • The LLVM/Clang Static analyzer can typically find memory management problems even before you run your program. LLVM / Clang静态分析器通常可以在运行程序之前就发现内存管理问题。
  • The Object Alloc instrument in the Instruments application (see Instruments User Guide ) can track object allocation and destruction. Instruments应用程序中的Object Alloc工具(请参见Instruments用户指南 )可以跟踪对象的分配和销毁。
  • Shark (see Shark User Guide ) also profiles memory allocations (amongst numerous other aspects of your program). Shark(请参阅《 Shark用户指南》 )还介绍了内存分配(在程序的许多其他方面)。

Having said that: You have to call [super dealloc] in the very last line of your dealloc method. 话虽如此:您必须在dealloc方法的最后一行调用[super dealloc] Besides that everything in your code should be ok. 除此之外,代码中的所有内容都应该可以。 Don't try to manually lower the retainCount. 不要尝试手动降低keepCount。 Use proper memory management. 使用适当的内存管理。 Again, do not look at the retainCount. 同样,不要看retainCount。

And you are not allowed to use an object after you have released it. 并且,释放对象后,您将无法使用它。 If the scroller would be deallocated because of your release the second NSLog would result in a BAD_ACCESS exception. 如果由于您的版本而释放了滚动条,则第二个NSLog将导致BAD_ACCESS异常。

This is why: 这就是为什么:

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.
  1. Methods beginning with init… return non-autoreleased instances with a retain count of 1. init…开头的方法返回保留值为1的非自动释放实例。
  2. Accessing your subview via self.view: returnes an autoreleased retained pointer to subview. 通过self.view:访问您的子视图self.view:将自动释放的保留指针返回到子视图。
  3. Adding a subview to a view via addSubview: retains the subview . 通过addSubview:向视图添加子视图addSubview: 保留subview
  4. Removing a subview from its superview via removeFromSuperview: releases it . 通过removeFromSuperview:从其子视图中删除子视图removeFromSuperview: 释放它

You should not rely on an object's retain count though. 但是,您不应依赖对象的保留计数。
Instead you must take care to level out retain and release calls on an object. 相反,您必须注意使对象上的保留和释放调用保持平衡。
Make sure to read Apple's Memory Management Programming Guide in this matter! 确保在此问题上阅读Apple的《 内存管理编程指南》 (the rules section in particular!) (尤其是规则部分 !)

self.view is retaining it. self.view保留了它。 When your UIViewController deallocs, it'll release self.view , which will release all its retained subviews. 当你的UIViewController deallocs,它会释放self.view ,这将释放所有保留的子视图。 In fact, you should probably release it soon after adding it to self.view . 实际上,您可能应该在将它添加到self.view之后尽快发布它。

That said, I strongly second @fluchtpunkt's answer. 就是说,我坚决支持@fluchtpunkt的回答。 Examining the retainCount property looking for debugging info will only lead to confusion and increasingly coherent and ranty posts on Stack Overflow. 检查retainCount属性以查找调试信息只会导致混乱,并且在Stack Overflow上会导致越来越连贯和混乱的帖子。

Previous answers are correct: don't use -retainCount, and make sure that you call [super dealloc] last in your own -dealloc implementation. 先前的答案是正确的:请勿使用-retainCount,并确保您在自己的-dealloc实现中最后调用[super dealloc]

I want to add that you'll probably never see a case (not that you should be looking) where -retainCount returns 0. If an object's retainCount drops to zero, the object is deallocated. 我想补充一下,您可能永远都不会看到-retainCount返回0的情况(不是您应该看的情况)。如果对象的keepCount下降为零,则对象将被释放。 In fact, it seems that Cocoa never even bothers to set the retainCount to zero... -release appears to deallocate the object if the previous retainCount was 1. Just one more reason to consider -retainCount to be a private implementation detail. 实际上,似乎Cocoa甚至都不会费心将keepCount设置为零...-如果以前的keepCount为1,则-release似乎会取消分配对象。这是将-retainCount作为私有实现细节的又一个原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM