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

时间:2012-07-31 10:43:06

标签: objective-c

我正在尝试使用Objective-C编程语言进一步了解详细信息。

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

Apple文档说“如果你不使用self。,你可以直接访问实例变量。(...)”

假设我有一个具有实例变量NSString *name的狗对象。

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

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

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

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

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

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

myDog.name = @"Yoda";

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

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

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

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

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

但是,您需要注意命名约定和方法的实现:

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

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

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