1

使用 ARC 定义 Person 类时,

  1. 我应该在初始化程序中使用self.fullname还是只使用fullname
  2. 如果我使用全名,传递的字符串会保留吗?
  3. 如果我使用self.fullname我必须定义一个 setter 或一个属性?我应该使用吗?

人员类初始化器

来自前 ARC 的思维方式,我正试图围绕 ARC 建议的变化。

4

3 回答 3

3
  1. 使用 ARC,它们的行为方式相同,只是self.fullname会通过 setter。默认设置器将为您提供 KVO 合规性。但除此之外,没有区别。
  2. 是的,如果指针被宣布为强,他们会的。
  3. 要使用self.fullname = ...,您必须定义一个 setter。对于 NSStrings 和其他具有可变变体的类,通常建议使用(copy).
于 2012-07-28T18:34:19.730 回答
2

在初始化程序中,我建议不要在 上调用任何方法self,因为该对象处于这种不寻常的状态,它缺乏自我一致性。对于您给出的简单示例,它不会立即产生影响。但是,如果您稍后定义自己的-setFullname:方法来读取或写入对象的任何其他部分,那么self.fullname =从您的初始化程序调用将导致问题,因为该对象尚未完全形成。

于 2012-07-28T19:05:50.823 回答
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;
  1. 你有一个实例变量。通常你会用下划线将你的 ivar 与属性称为相同的名称,但通常你会发现 ivar 和属性具有相同的名称。
  2. 也可以声明一个属性,在这种情况下,编译器会自动为你插入一个带下划线的 ivar!

现在重要的是要理解,和之间有一个主要区别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

对您的问题的简短回答

  1. 如果不需要两者,请不要使用 ivar和属性
  2. self.property = newValue 通过其 setter 方法设置新值
  3. ivar = newValue 直接设置新值,绕过任何setter方法
  4. 如果有 setter 方法,绝对建议使用访问器并且不要直接设置 ivars(换句话说:如果你有一个属性,通过调用 self.property = newValue 来使用它的 setter)
于 2012-07-28T19:35:19.640 回答