7

From Apple documentation about Memory Management :

The only places you shouldn’t use accessor methods to set an instance variable are in init methods and dealloc. To initialize a counter object with a number object representing zero, you might implement an init method as follows:

To allow a counter to be initialized with a count other than zero, you might implement an initWithCount: method as follows:

- initWithCount:(NSNumber *)startingCount {
    self = [super init];
    if (self) {
        count = [startingCount copy];
    }
    return self;
}

Why not ?

Pierre Valade
  • 3,388
  • 3
  • 24
  • 29
  • can you add a link to your documentation source? – Scott M. Aug 06 '10 at 14:01
  • possible duplicate of [Why shouldn't I use Obective C 2.0 accessors in init/dealloc? ](http://stackoverflow.com/questions/192721/why-shouldnt-i-use-obective-c-2-0-accessors-in-init-dealloc) – Alex Rozanski Aug 06 '10 at 14:24
  • @Scott: I've just added a link in the question itself. – Pierre Valade Aug 06 '10 at 15:02
  • possible duplicate of [Objective-C Dot Syntax and Init](http://stackoverflow.com/questions/3150494/objective-c-dot-syntax-and-init) – JeremyP Aug 06 '10 at 15:34
  • Building and tearing down a house isn’t the same than living in it: http://stackoverflow.com/questions/3402234/properties-in-dealloc-release-then-set-to-nil-or-simply-release/3408931#3408931 Greetings –  Aug 06 '10 at 20:51
  • Even if I can't find a clear and simple answer, I guess that Perspx is right, this is a duplicate with this [question](http://stackoverflow.com/questions/192721/why-shouldnt-i-use-obective-c-2-0-accessors-in-init-dealloc). – Pierre Valade Aug 06 '10 at 15:09

4 Answers4

16

See my answer to this question.

The main reason why is because a subclass might override your accessors and do something different. The subclass's accessors might assume a fully initialised object i.e. that all the code in the subclass's init method has run. In fact, none of it has when your init method is running. Similarly, the subclass's accessors may depend on the subclass's dealloc method not having run. This is clearly false when your dealloc method is running.

To expand on your example, if you had instead done

- initWithCount:(NSNumber *)startingCount {
    self = [super init];
    if (self) {
        [self setCount: [startingCount copy]];
    }
    return self;
}

but a subclass had overridden setCount: to do something other than set your count variable, you could be in trouble.

Community
  • 1
  • 1
JeremyP
  • 84,577
  • 15
  • 123
  • 161
2

JeremyP made a good point. Since the syntax of setter invocation always involves "self", whose type is determined at runtime, so a subclass instance could call its overridden version of setter, if "self" is truly a subclass object...

However, there are some cases in which you must use the setter in an initializer. This is when the instance variable is declared within a superclass; you can NOT access the instance variable directly anyway, so you must use the setter.

Another situation is when the property uses lazy initialization. In this case, you have to go via the getter; if you don’t, the instance variable will never get a chance to be initialized. For example, the EOCPerson class might have a property to give access to a complex object repre- senting each person’s brain. If this property is infrequently accessed and expensive to set up, you might initialize it lazily in the getter, like this:

- (EOCBrain*)brain { if (!_brain) {
        _brain = [Brain new];
    }
return _brain; }

If you were to access the instance variable directly and the getter had not been called yet, brain would not have been set up, and you would have to call the accessor for all accesses to the brain property.

-- Matt Galloway's EOC book Item7

J-Q
  • 374
  • 5
  • 15
1

just from an OOP point of view (since I have no experience with objective-c), you would not use methods of the object which is currently being constructed. This is possible in some languages, but you already have access to the private variables. The object construction isn't completed yet, so it isn't ready to be operated on. Once the object is constructed it is in a known good state (or so it is assumed) and it can perform.

Scott M.
  • 7,313
  • 30
  • 39
  • Yes, I understand that if you redefined the init method that could be a problem of self recursion. But if you define another method like initWithCount, I don't get the point from a technical point of view. – Pierre Valade Aug 06 '10 at 13:58
  • Class, instance and static methods are static objects which are created when the class object is created. Strictly speaking, there is no OOP language where constructors create instances--they're just syntactically protected instance methods that *need* to be bound to an instance which is created and supplied to the constructor when invoked--which is to say that there isn't any such OOP language where your not allowed to access instance methods in the constructor when you already have an instance to work with. – Filip Dupanović Jan 04 '13 at 13:04
-3

In modern day objective C, you SHOULD be able to use accessor methods within init. Compiler faults will RARELY if ALMOST NEVER happen

SleepsOnNewspapers
  • 3,353
  • 3
  • 23
  • 29