Search code examples
objective-cpropertiesinitializationaccessordealloc

Valid use of accessors in init and dealloc methods?


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:

  1. How am I supposed to initialize someObject without using the accessor? You might say that the compiler (or runtime or whatever) will ensure that someObject is already set to nil, but I believe it would be improper behavior to rely on that. Having a decent background in C, I've seen a fair number of bugs due to not properly initializing variables, and this seems little different.
  2. How can I release someObject if I'm not supposed to use the accessor in the dealloc method?

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?


Solution

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