Mixing properties and ivars 属性和实例变量的混用

其实嘞,我前面所说的「你不再需要担心实例对象」这句话有一半是错的(跑路)确实在 Xcode 4.4 之后,就不需要在手动创建实例变量了,毕竟大多数情况下,用到属性也就是用用属性的方法,但是其实有的时候还是需要有实例变量哒。

在你到 @property 声明了 name 属性的时候,Xcode 除了创建 name 和 setName 方法之外,它还创建了一个叫 _name 的实例变量,然后把两个方法整合起来,这个过程叫做「合成一个实例变量」(synthesize an ivar)。也就是说,你创建了一个属性,接下来的事情就是 Xcode 的了。

前面我已经用两种方法演示了如何获取属性,点语法和访问器。其实这里还有第三种方法,这种方法绕开了整个属性,而是直接获取合成到的那个实例变量。这种方法在 Objective-C 里面非常常用,看就是这样:

- (void)printGreeting {
    NSLog(@"Hello, %@!", _name);
}

苹果的官方文档明确指出,这么做是不好的。但是几乎在所有项目里,都能看到大家这样写,也很好理解,方便嘛。当然啦,确实也是有特殊情况的,那种状况下就是需要获取直接获取实例变量的。

_name 的命名是要 Xcode 自动生成的,生成规则是属性名加下划线,你也可以自己来定义这个实例变量的名称,定义的方法是加上 @synthesize,具体还是看代码:

@implementation Person
@synthesize name = userName;
- (void)printGreeting {
    NSLog(@"Hello, %@!", userName);
} @end

这里就把 name 属性的实例变量命名为了 userName,也就是说,我们在 printGreeting 方法里可以直接获取这个实例变量。

还有个捷径,就像这样子:

@synthesize name;
@synthesize name = _name;

这第一行的意思是「把 name 属性的实例变量命名为 name」,这么做真的有毒,因为它会把属性和实例变量搞得傻傻分不清楚。

而第二行的意思是「把 name 属性的实例变量命名为 _name」,这一步其实就是把 Xcode 后台所做的事情用代码表现了出来。这种类型的代码会在后面我们自定义 get 和 set 访问器的时候经常看到。

results matching ""

    No results matching ""