I am testing the following code below. ffv is declared in the interface file.
ffv = [[FullFunctionView alloc] initWithFrame:self.view.bounds];
NSLog(@"%i", [ffv retainCount]); // prints 1
[self.view insertSubview:ffv belowSubview:switchViewsBtn];
NSLog(@"%i", [ffv retainCount]); // prints 2
[ffv release]; // you can release it now since the view has ownership of ffv
NSLog(@"%i", [ffv retainCount]); // prints 1
if (ffv == nil)
NSLog(@"ffv is nil");
// "ffv is nil" is not printed
[ffv testMethod]; // "test method called" is printed
this is my [ffv testMethod] implementation
- (void)testMethod
{
NSLog(@"test method called");
}
What I deduce in this case is that even if you release an object with retain count 2, you lose ownership of that object however, the reference is still kept.
Now, my question are:
- Is my deduction correct?
- Is there anything else important that can be deduced from this?
- What are the complications caused by still keeping (using) ffv and calling methods from ffv? (My opinion is that this is ok since the view will always own ffv and won’t release it until someone calls viewDidUnload. And as long as I don’t pass ffv’s reference to other objects.)
Your deduction is correct. The Memory Management Programming Guide explains that each object has one or many owners. You own any object you create using any method starting with
alloc,new,copy, ormutableCopy. You can also take ownership of an object using retain. When you’re done with an object, you must relinquish ownership usingreleaseorautorelease.Releasing the object doesn’t change the value of any variables that reference that object. Your variable contains the object’s memory address until you reassign it, no matter what retain count the object has. Even if the object’s retain count goes to zero, causing the object to get deallocated, your variable will still point at that same address. If you try to access the object after it’s been deallocated, your app will normally crash with EXC_BAD_ACCESS. This is a common memory management bug.
Nothing comes to mind.
When you call
release, you are telling the Objective C runtime that you no longer require access to the object. While there may be many cases like this one in which you know the object will still exist, in practice you really shouldn’t access an object after callingrelease. You’d just be tempting fate and setting yourself up for future bugs.I personally don’t like peppering my code with
releasestatements, because I don’t trust myself to remember them 100% of the time. Instead, I prefer to autorelease my variables as soon as I allocate them like this:This guarantees that ffv will exist at least until the end of the method. It will get released shortly thereafter, typically before the next iteration of the run loop. (In theory this could consume excessive memory if you’re allocating a large number of temporary objects in a tight loop, but in practice I’ve never encountered this case. If I ever do, it will be easy to optimize.)