I've heard now from several sources (stackoverflow.com, cocoa-dev, the documentation, blogs, etc) that it is "wrong" to use accessors and settings (foo, setFoo:) in your init and dealloc methods. I understand that there is there is a remote possibility of confusing other objects that are observing the property if you do so. (a simple example is given here)
However, I have to say that I don't agree with this practice for the following reason:
The new Objective-C runtime (the one on the iPhone and the 64-bit runtime in 10.5) allows you to declare properties without declaring a corresponding ivar. For example, the following class will compile just fine on 10.5 or for the iPhone (device, not simulator):
@interface Foo : NSObject { }
@property (retain) id someObject;
@end
@implementation Foo
@synthesize someObject;
@end
Understanding that the above is a perfectly valid Objective-C class, let's say I decide to write an initializer, and for memory management purposes, a dealloc method (since GC is not available on the iPhone). Everything I've ever read about initializers and deallocation would lead me to write the following two methods:
- (id) init {
if (self = [super init]) {
//initialize the value of someObject to nil
[self setSomeObject:nil];
}
return self;
}
- (void) dealloc {
//setting someObject to nil will release the previous value
[self setSomeObject:nil];
[super dealloc];
}
However, according to the documentation and popular opinion, this is "wrong". So my questions are this:
If the answer to either of these is "you can't", then how can it be bad to use accessors in your init and dealloc methods?
I understand that the current 10.5 behavior under which the synthesized ivars are not directly accessible is considered by Apple to be a bug; you should be able to directly access it, but can't.
Hence, you should be able to do:
someObject = nil;
instead of
self.someObject = nil;
In the meantime, using the accessor directly is the only way to do it without providing an explicit ivar.
Update: This bug has been fixed; you can now do someObject = nil
just fine.