开发者

Objective-C retain question

开发者 https://www.devze.com 2023-02-25 12:15 出处:网络
In Xcode I have a UINavigationController on wichh I push a UIViewController. In that UIViewController I init an UIScrollView.

In Xcode I have a UINavigationController on wichh I push a UIViewController.

In that UIViewController I init an 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.

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.

Kind regards,

Tom


Do not use 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.
  • The Object Alloc instrument in the Instruments application (see Instruments User Guide) can track object allocation and destruction.
  • Shark (see Shark User Guide) also profiles memory allocations (amongst numerous other aspects of your program).

Having said that: You have to call [super dealloc] in the very last line of your dealloc method. Besides that everything in your code should be ok. Don't try to manually lower the retainCount. Use proper memory management. Again, do not look at the 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.


self.view is retaining it. When your UIViewController deallocs, it'll release self.view, which will release all its retained subviews. In fact, you should probably release it soon after adding it to self.view.

That said, I strongly second @fluchtpunkt's answer. Examining the retainCount property looking for debugging info will only lead to confusion and increasingly coherent and ranty posts on Stack Overflow.


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.
  2. Accessing your subview via self.view: returnes an autoreleased retained pointer to subview.
  3. Adding a subview to a view via addSubview: retains the subview.
  4. Removing a subview from its superview via removeFromSuperview: releases it.

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! (the rules section in particular!)


Previous answers are correct: don't use -retainCount, and make sure that you call [super dealloc] last in your own -dealloc implementation.

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. 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号