2012-07-31 59 views
3

我正在试图更详细地介绍Objective-C编程语言。Objective-C实例变量访问器方法

现在我有一个关于在设置数值时调用[self]的问题。

苹果的文件说:“如果你不使用的自我。你直接访问实例变量。(......)”

因此,假设我有一个具有可变NSString *name实例的狗对象。

我创建像这样的实例变量设定器,而无需使用[self]关键字:

(void)setName:(NSString *)_name 
{ 
    name = _name; 
} 

当我替代地使用[自]关键字创建一个setter它看起来像这样:

(void)setName:(NSString *)_name 
{ 
    self->name = _name; 
} 

在主要方法中,我创建一个新的狗对象并设置并返回其名称值:

Dog *myDog = [[Dog alloc] init]; 

myDog.name = @"Yoda"; 

NSLog(@"name of the dog: %@", myDog.name); 

在这两种情况下,我都会得到尤达的回报值。但是在技术上,有没有[self]的实例变量调用之间的区别在哪里?是不是我使用setter方法调用相同的变量(内存)?

回答

1

self是物体本身的隐式引用,并且一般只真正需要SPECI FY它,当一个参数和实例变量具有相同的名称,例如,如果您有:

(void)setName:(NSString *)name 
{ 
    self->name = name; // self used here to differentiate between param and ivar 
} 

但是,你必须小心你的命名约定和执行方法:

  1. 一般前导下划线用作约定来命名实例变量,而不是传递给方法的参数。
  2. 为了设置NSString *对象,通常您需要使用retain它来获取对象的所有权并避免它被释放(稍后访问时会导致异常)。

因此您setName方法应该看起来更像是这样的:

// _name is the instance variable 
- (void)setName:(NSString *)name 
{ 
    [name retain]; 
    [_name release]; 
    _name = name; 
} 

这是唯一真正的,如果你正在使用的不是ARC MRR,但你不指定,所以我会假设你正在使用MRR。

+0

谢谢,第一部分我很清楚。我不明白你为什么'保留'setter中的'name'对象。我猜想我只需要setter中的'name'对象,并且在将它分配给实例变量'_name'后,它可以被释放,而'_name'应该被保留以备后用? – MrBr 2012-07-31 11:13:06

+0

@MrBr这一切都取决于您是否使用自动引用计数(ARC)。如果你是那么你不必担心,你的版本会好起来的。 – trojanfoe 2012-07-31 11:17:47

1

还有就是你的两个例子没有什么区别,在这两种情况下,你要修改的实例变量直接

自我它意味着self.name它使用setter方法[self setName:someValue];

self->name只是意味着它正在访问一个实例变量,所以

self->ivar = someVal; 
//is the same as 
ivar = someVal; 
+0

'self.name'与'[self setName:name]'相同,不是'self-> name'。 – trojanfoe 2012-07-31 10:51:06

+0

@trojanfoe正确,这就是我说的,我会编辑,使其更清晰 – wattson12 2012-07-31 10:52:12

+0

好,所以在这两种情况下,我在同一个变量(这是说我分配在内存中的同一个地方)操作? – MrBr 2012-07-31 10:53:28