This will be a short post, but there was a lot behind it. Trust me!
A few times, I’ve run into cases where my code didn’t run as expected. I’d initialize an object (sometimes in viewDidLoad()). Later, maybe in viewWillAppear(), or in a button delegate, I’d try to access that object and use it. The debugger would show an EXC_BAD_ACCESS. I’d step through the code and sometimes, the object would appear normal in the inspector. Other times, the debugger would think it was of a different type!?!
The cause, it seems was that when I initialized the object, I set autorelease, like this;
memberVariable = [[[MyObject alloc] initWithParam:param] autorelease];
I thought I was being smart by allow the object to be cleaned up for me. In fact, I was causing a problem because I apparently don’t understand the behavior of autorelease. It turns out it can cause objects to be released early. I would say avoid autorelease! It has bitten me several times now!
I also had problems understanding this. There’s actually no error in autorelease. You just have to really understand when it releases.
The problem with your code…
memberVariable = [[[MyObject alloc] initWithParam:param] autorelease];
…is that the local instance is autoreleased but the memberVariable is not retained. For this reason, I personally adopted a style convension of always creating properties with the (retain) flag for all of my member variables and naming the instance variables with an _.
The proper way to do it is:
in .h
interface MyClass
{
NSObject* _memberVariable;
}
@property (retain) NSObject* memberVariable;
in .m
@synthese memberVariable = _memberVariable;
-(void)foo
{
self.memberVariable = [[[MyObject alloc] initWithParam:param] autorelease];
}
-(void)dealloc
{
self.memberVariable = nil; // will release and set to null
}