Objective-C实例变量访问器方法



我正在尝试使用Objective-C编程语言了解更多细节。

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

苹果公司的文档中写道:"如果你不使用self.,你可以直接访问实例变量。(…)"

所以假设我有一个dog对象,它有一个实例变量NSString *name

我为这个实例变量创建了一个setter,就像这样,而不使用[self]关键字:

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

当我用[self]关键字创建一个setter时,它看起来像这样:

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

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

Dog *myDog = [[Dog alloc] init];
myDog.name = @"Yoda";
NSLog(@"name of the dog: %@", myDog.name);

在这两种情况下,我都会得到Yoda的返回值。但是,从技术上讲,带有和不带有[self]的实例变量调用之间的区别在哪里?是不是我调用了同一个变量(内存)而不使用setter方法?

self是对对象本身的隐式引用,通常只有当参数和实例变量具有相同名称时,才真正需要指定它,例如,如果您具有:

(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;
}

只有当您使用MRR而不是ARC时,这才是正确的,但您没有指定,所以我假设您使用的是MRR。

您的两个示例之间没有区别,在这两种情况下,您都是直接修改实例变量

就其本身而言,它是指使用设置方法[self setName:someValue];self.name

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

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

最新更新