Should I refer to self.property in the init method with ARC?

Objective CIos5InitializationAutomatic Ref-CountingReference Counting

Objective C Problem Overview


A quick question.

if I have a property and an ivar declared with the same name:

in the .h file:

(Reminder*)reminder;
@property(nonatomic,strong)(Reminder*)reminder;

in the .m file, should I use the ivar or the property in the init method if I'm using ARC?

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        reminder = reminder_;
    }
    return self;
}

Or should I use the property to get the benefit of the automatic reference counting like this:

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        self.reminder = reminder_;
    }
    return self;
}

I'm not sure at which point in the object's initialization the properties become accessible with the dot notation.

Objective C Solutions


Solution 1 - Objective C

Use direct access in partially constructed states, regardless of ARC:

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        reminder = reminder_;
        // OR
        reminder = [reminder_ retain];
    }
    return self;
}

This is because self.whatever will trigger other side effects, such as Key-Value Observing (KVO) notifications, or maybe your class implements (explicitly) or a subclass overrides setWhatever: -- and that could expose your partially initialized instance to other APIs (including its own), which rightly assume they are dealing with a fully constructed object.

You could manually verify that a class is capable of operating in a partially initialized state, but that requires a lot maintenance and is (frankly) impractical or impossible when other people want to subclass your class. It requires a lot of time and maintenance, and there isn't substantiative benefit doing so, especially if you try to use the approach as a convention.

So the uniform manner which guarantees correctness is to use direct access in partially constructed states, and avoid using the accessors.

Note: I am using "partially constructed" because initialization is only half of the picture; -dealloc has similar caveats.

Some more detail as to why you should use direct access in partially constructed states (ARC || MRC) can be found here: https://stackoverflow.com/questions/5932677/initializing-a-property-dot-notation/5932733#5932733

Solution 2 - Objective C

No you shouldn't!

You can find description why here
Also apple recommend to don't do it. Read here

Solution 3 - Objective C

> I'm not sure at which point in the object's initialization the properties become accessible with the dot notation.

Since the dot notation is still an Objective-C method (and a C method actually under the ObjC method) the dot notation, or calling the method, is perfectly safe GIVEN the method is prepared to deal with underlying type(s) in memory in whatever state they happen to be in. The normal rule about avoiding use of an uninitiatilized (possibly) garage memory segment still would apply. Which is the strongest motivation for use of the ivar in the init.

But if your method (getter|setter) is capable of correctly using the memory segment - independent of whether it is first written to before being read - then by all means use your getter in the init method. A Lazy getter takes advantage of the assumption that a pointer it will initialize starts as 'nil' to decide on performing the initialization. If you cannot assume the initial contents of your memory then initializing the ivar might be the safest course.

Why have the rule of never using setters or getters in the init if the method is capable of operating correctly in this scenario?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex StoneView Question on Stackoverflow
Solution 1 - Objective CjustinView Answer on Stackoverflow
Solution 2 - Objective CKostiantyn KovalView Answer on Stackoverflow
Solution 3 - Objective Cuser1864957View Answer on Stackoverflow