Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why shouldn't I use Objective C 2.0 accessors in init/dealloc? [closed]

In @mmalc's response to this question he states that "In general you should not use accessor methods in dealloc (or init)." Why does mmalc say this?

The only really reasons I can think of are performance and avoiding unknown side-effects of @dynamic setters.

Discussion?

like image 407
schwa Avatar asked Oct 10 '08 19:10

schwa


2 Answers

It's basically a guideline to minimize the potential for bugs.

In this case there is the (possibility) that your setter/getter may inadvertently make direct or indirect assumptions about the state of the object. These assumptions could be a problem when the object is in the midst of being setup or destroyed.

For example in the code below the observer does not know that 'Example' is being destroyed and could assume that other properties, which have already been freed, are valid.

(You could argue that your object should remove all observers before tearing itself down, which would be good practice, and another guideline to prevent inadvertent problems).

@implementation Example  -(void) setFoo:(Foo*)foo {    _foo = foo;   [_observer onPropertyChange:self object:foo]; }  -(void) dealloc {    ...    self.foo = nil; }  @end 
like image 127
Andrew Grant Avatar answered Oct 03 '22 02:10

Andrew Grant


It is all about using idiomatically consistent code. If you pattern all of your code appropriately there are sets of rules that guarantee that using an accessor in init/dealloc is safe.

The big issue is that (as mmalc said) the code the sets up the properties default state should not go through an accessor because it leads to all sorts of nasty issues. The catch is that there is no reason init has to setup the default state of a property. For a number of reasons I have been moving to accessors that self initialize, like the simple example below:

- (NSMutableDictionary *) myMutableDict {     if (!myMutableDict) {         myMutableDict = [[NSMutableDictionary alloc] init];     }      return myMutableDict; } 

This style of property initialization allows one to defer a lot of init code that may not actually be necessary. In the above case init is not responsible for initing the properties state, and it is completely safe (even necessary) for one to use the accessors in the init method.

Admittedly this does impose additional restrictions on your code, for instance, subclasses with custom accessors for a property in the superclass must call the superclasses accessor, but those restrictions are not out of line with various other restrictions common in Cocoa.

like image 43
Louis Gerbarg Avatar answered Oct 03 '22 02:10

Louis Gerbarg