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

十年热恋 提交于 2019-11-26 04:37:01

问题


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.


回答1:


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: Initializing a property, dot notation




回答2:


No you shouldn't!

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




回答3:


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?



来源:https://stackoverflow.com/questions/8056188/should-i-refer-to-self-property-in-the-init-method-with-arc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!