Ale*_*one 50 initialization reference-counting objective-c ios5 automatic-ref-counting
一个简单的问题.
如果我有一个属性和一个声明同名的ivar:
在.h文件中:
(Reminder*)reminder;
@property(nonatomic,strong)(Reminder*)reminder;
Run Code Online (Sandbox Code Playgroud)
在.m文件中,如果我使用ARC,我应该在init方法中使用ivar还是属性?
- (id)initWithReminder:(Reminder*)reminder_ {
self = [super init];
if (self) {
reminder = reminder_;
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
或者我应该使用该属性来获得自动引用计数的好处,如下所示:
- (id)initWithReminder:(Reminder*)reminder_ {
self = [super init];
if (self) {
self.reminder = reminder_;
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
我不确定在对象的初始化中哪个点可以使用点表示法访问属性.
jus*_*tin 67
无论ARC如何,在部分构造的状态下使用直接访问:
- (id)initWithReminder:(Reminder*)reminder_ {
self = [super init];
if (self) {
reminder = reminder_;
// OR
reminder = [reminder_ retain];
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
这是因为self.whatever
会触发其他副作用,例如键值观察(KVO)通知,或者您的类实现(显式)或子类覆盖setWhatever:
- 并且可能将部分初始化的实例暴露给其他API(包括它自己的) ,正确地假设他们正在处理一个完全构造的对象.
您可以手动验证某个类是否能够以部分初始化状态运行,但这需要大量维护,并且(当然)当其他人想要为您的类创建子类时,这是不切实际或不可能的.它需要大量的时间和维护,并且没有这样做的实质性好处,特别是如果您尝试将该方法用作约定.
因此,保证正确性的统一方式是在部分构造的状态中使用直接访问,并避免使用访问器.
注意:我使用"部分构造",因为初始化只是图片的一半; -dealloc
有类似的警告.
有关为什么应该在部分构造状态(ARC || MRC)中使用直接访问的更多细节可以在这里找到:初始化属性,点表示法