使用ARC定义Person类时,
来自ARC之前思考的方式,我试图围绕ARC建议的变化。
答案 0 :(得分:3)
self.fullname
将通过setter。默认的setter将为您提供KVO合规性。但除此之外,没有区别。self.fullname = ...
,您必须定义一个setter。对于NSStrings和其他具有可变变体的类,通常建议使用(copy)
。答案 1 :(得分:2)
在初始化器中,我建议反对调用self
上的任何方法,因为该对象处于缺乏自我一致性的异常状态。对于您给出的简单示例,它不会立即产生影响。但是,如果您稍后定义了自己的-setFullname:
方法来读取或写入对象的任何其他部分,则从初始化程序调用{{1}}将导致问题,因为该对象尚未完全形成。
答案 2 :(得分:2)
我认为可用的答案需要一些澄清。
看看这个标题:
Person : NSObject {
NSString *name; // better to call this _name to not confuse it with the property
// and even more better to not use an ivar, but only a property
}
@property (strong) NSString *name;
现在重要的是要理解,name = @"John Smith"
和self.name = @"John Smith"
之间存在一个主要区别,第一个直接设置实例变量(又名_name = @"John Smith"
,忽略内存管理和(没有ARC)如果前一个值不是nil则创建泄漏。使用self-dot-syntax(self.name)使用自动生成的访问器(= setter方法),它尊重所选的内存管理(通常保留或强或复制)。
在属性之前和ARC之前,对象设置器看起来像这样:
-(void)setName:(NSString*)newName {
if(newName != name) {
[name release];
name = newName;
[newName retain];
}
}
这意味着,将释放旧的iVar值并保留新的iVar值。一切都平衡而且很好。
现在,使用ARC和合成访问器(属性),您不必关心所有这些。当Properties合成acessors时,ARC会根据您的代码分析合成并平衡保留/释放调用。所以ARC和属性并不一定要求彼此,因为它们综合了不同的方面(注意例如不同的语法" __弱"在ivar声明和"(弱)"在属性宣言?)。但知道它如何运作有用,因为现在你会发现它们之间存在重大差异
name = @"John Smith"; // directly access ivar, the old value is never released
// your program is leaking if you're not using ARC
并通过合成访问器
self.name = @"John Smith"; // old ivar released, new ivar set, all okay