3

我正在尝试更详细地了解 Objective-C 编程语言。

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

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

所以假设我有一个带有实例变量的狗对象NSString *name

我为这样的实例变量创建了一个设置器,而不使用[self]关键字:

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

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

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

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

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

myDog.name = @"Yoda";

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

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

4

2 回答 2

1

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

self.name通过 self 是使用 setter 方法的含义[self setName:someValue];

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

self->ivar = someVal;
//is the same as
ivar = someVal;
于 2012-07-31T10:50:14.613 回答
1

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。

于 2012-07-31T11:00:06.043 回答