Why shouldn't I use Objective-C 2.0 accessors in init / dealloc?

In @mmalc, the answer to this question is that he states, "In general, you should not use access methods in dealloc (or init)." Why does MMALC say this?

The only reasons I can think of are performance and avoiding the unknown side effects of @dynamic seters.

Discussion

+41
objective-c cocoa
Oct 10 '08 at 19:21
source share
6 answers

It's all about using idiomatically consistent code. If you structure your code correctly, there are many rules that guarantee that using accessor in init / dealloc is safe.

The big problem is that (as mmalc said) the code setting the state of the property by default should not go through the accessor, because it leads to various unpleasant problems. The trap is that there is no reason why init should configure the default state of a property. For a number of reasons, I switched to accessors that initialize themselves, such as a simple example:

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

This style of property initialization allows you to delay a lot of initialization code, which may not actually be necessary. In the above case, init is not responsible for initializing the state of properties, and it is absolutely safe (even necessary) in order to use accessors in the init method.

Admittedly, this imposes additional restrictions on your code, for example, subclasses with custom accessories for a property in the superclass must call the supermarket, but these restrictions do not contradict other other restrictions common in Cocoa.

+19
Oct 22 '08 at 21:10
source share

This is basically a recommendation to minimize the chance of errors.

In this case, there is (the possibility) that your setter / recipient may inadvertently make direct or indirect assumptions about the state of the object. These assumptions can be a problem when an object is in the process of being installed or destroyed.

For example, in the code below, the observer does not know that the β€œexample” is being destroyed and can assume that other properties that have already been released are valid.

(You could argue that your facility should remove all observers before coming off, which would be good practice, and another guide to prevent unintentional problems).

 @implementation Example -(void) setFoo:(Foo*)foo { _foo = foo; [_observer onPropertyChange:self object:foo]; } -(void) dealloc { ... self.foo = nil; } @end 
+29
Oct 10 '08 at 20:00
source share

You answered your question:

  • Performance can be a completely adequate reason in itself (especially if your accessors are atomic).
  • You should avoid any side effects that accessors may have.

The latter is especially important if your class can be a subclass.

It is not clear why this is specifically addressed in Objective-C 2 accessories? The same principles apply whether you use declared properties or accessors themselves for writing.

+15
11 Oct '08 at 9:08
source share

Perhaps the installer has a logic that needs to be executed, or perhaps the implementation uses ivar with a name other than a getter / setter, or maybe two ivars that need to be released and / or have a value of zero. The only sure way is to call the setter. The answer is the responsibility of the collector in such a way that unwanted side effects do not occur when called during init or dealloc.

From Cocoa Design Patterns, "Buck, Yacktman, p. 115:" ... there is no practical alternative to using accessories when using synthesized instance variables with a modern version of Objective-C or ... "

+2
Oct 16 '09 at 17:52
source share

In fact, for a class that comes and goes quite often (for example, a detailed view controller), you want to use an accessor in init; otherwise, you could release the value in viewDidUnload, which you are trying to access later (they show that in CS193P ...)

0
Jan 03 2018-11-11T00:
source share

You can create the same problems by NOT assigning an installer during distribution / release.

I do not think that you can achieve anything using save / release directly in init / dealloc. You just change the set of possible errors.

Every time you have to think about the procedure for distribution / release of property.

0
Dec 09 '11 at 20:57
source share



All Articles