使用 ARC 定义 Person 类时,
- 我应该在初始化程序中使用self.fullname还是只使用fullname?
- 如果我使用全名,传递的字符串会保留吗?
- 如果我使用self.fullname我必须定义一个 setter 或一个属性?我应该使用强吗?
来自前 ARC 的思维方式,我正试图围绕 ARC 建议的变化。
使用 ARC 定义 Person 类时,
来自前 ARC 的思维方式,我正试图围绕 ARC 建议的变化。
self.fullname
会通过 setter。默认设置器将为您提供 KVO 合规性。但除此之外,没有区别。self.fullname = ...
,您必须定义一个 setter。对于 NSStrings 和其他具有可变变体的类,通常建议使用(copy)
.在初始化程序中,我建议不要在 上调用任何方法self
,因为该对象处于这种不寻常的状态,它缺乏自我一致性。对于您给出的简单示例,它不会立即产生影响。但是,如果您稍后定义自己的-setFullname:
方法来读取或写入对象的任何其他部分,那么self.fullname =
从您的初始化程序调用将导致问题,因为该对象尚未完全形成。
我认为可用的答案需要一些澄清。
看看这个标题:
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)如果前一个值不为零则创建泄漏。使用 self- dot-syntax (self.name) 使用自动生成的访问器(=setter 方法),它尊重所选的内存管理(通常是保留或强或复制)。
在属性之前和 ARC 之前,对象设置器看起来像这样:
-(void)setName:(NSString*)newName {
if(newName != name) {
[name release];
name = newName;
[newName retain];
}
}
这意味着,旧的 iVar 值被释放并保留新的 iVar 值。所有的平衡和罚款。
现在,使用 ARC 和综合访问器(属性),您不必关心所有这些。属性综合存取器,而 ARC 根据对代码的分析综合和平衡保留/释放调用。因此 ARC 和属性不一定相互要求,因为它们综合了不同的方面(例如,请注意 ivar 声明中的不同语法“__weak”和属性声明中的“(weak)”?)。但了解它过去是如何工作的很有用,因为现在您会发现两者之间存在重大差异
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