一个简短的问题.

如果我有一个财产和一个使用相同名称声明的ivar:

在教室里.h文件:

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

在教室里.m文件,如果我使用的是ARC,我应该使用ivar还是init方法中的属性?

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

或者我应该使用该属性来获得自动引用计数的好处,如下所示:

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

我不确定在对象初始化的哪一点上,属性可以通过点符号访问.

推荐答案

在部分构造的状态下使用直接访问,而不考虑弧:

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

这是因为self.whatever将触发其他副作用,例如键值观察(KVO)通知,或者您的类(显式地)实现或子类重写setWhatever:——这可能会将您部分初始化的实例expose 给其他API(包括它自己的API),正确地假设他们正在处理一个完全构造的对象.

您可以手动验证一个类是否能够在部分初始化状态下运行,但这需要大量维护,而且(坦率地说)在其他人想要对您的类进行子类化时是不切实际或不可能的.它需要大量的时间和维护,而且这样做没有实质性的好处,尤其是如果你试图将这种方法作为惯例使用的话.

因此,保证正确性的统一方式是在部分构造状态下使用直接访问,并避免使用访问器.

注意:我使用"部分构造",因为初始化只是图片的一半;-dealloc也有类似的警告.

关于为什么应该在部分构造状态(ARC | | MRC)中使用直接访问,可以在这里找到更多细节:Initializing a property, dot notation

Objective-c相关问答推荐

警告:格式字符串不是字符串文字(可能不安全)

Objective-c中release和dealloc的区别

Xcode 预处理器输出

iOS 应用程序下一个键不会转到下一个文本字段

为 iphone 应用程序设置自动构建服务器的最佳实践?

从日、月、年生成 NSDate

从 NSString 创建 SHA1 哈希

Iphone,获取 NSArray 中的国家/地区列表

在Objective-C中从类名的NSString创建对象

UIScreen MainScreen Bounds 返回错误的大小

UICollectionView 标头未显示

如何判断特定的 ViewController 视图当前是否可见?

我们可以在 UIPageViewController 中自定义页面指示器吗?

如何从 AVPlayer(不是 AVAudioPlayer)获取持续时间?

如何在情节提要场景中嵌入自定义视图 xib?

首次提交应用内购买以供审核

Objective-C 中的 super 到底是什么?

嵌入自定义容器视图控制器时,内容位于导航栏下方.

Xcode 如何加载主情节提要?

iOS中的活动生命周期相当于什么?