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

Objective-C实例变量访问器方法,objective-c,Objective C,我试图用Objective-C编程语言更详细地了解 现在我有一个关于设置值时调用[self]的问题 Apple文档中说“如果不使用self,则直接访问实例变量。(…) 所以假设我有一个dog对象,它有一个实例变量NSString*name 我像这样为该实例变量创建setter,而不使用[self]关键字: (void)setName:(NSString *)_name { name = _name; } 当我使用[self]关键字创建setter时,它如下所示: (void)setName

我试图用Objective-C编程语言更详细地了解

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

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

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

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

(void)setName:(NSString *)_name
{
  name = _name;
}
当我使用[self]关键字创建setter时,它如下所示:

(void)setName:(NSString *)_name
{
  self->name = _name;
}
// _name is the instance variable
- (void)setName:(NSString *)name
{
    [name retain];
    [_name release];
    _name = name;
}
在main方法中,我创建了一个新的dog对象,并设置并返回其名称值:

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

myDog.name = @"Yoda";

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

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

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

self的意思是
self.name
,它使用setter方法
[self-setName:someValue]

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

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

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

(void)setName:(NSString *)name
{
  self->name = name;    // self used here to differentiate between param and ivar
}
但是,您需要注意命名约定和方法的实现:

  • 通常,前导下划线用作命名实例变量的约定,而不是传递给方法的参数
  • 为了设置
    NSString*
    对象,通常需要
    保留它,以获得对象的所有权并避免它被释放(这将在以后访问它时导致异常)
  • 因此,您的
    setName
    方法应该更像这样:

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

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

    self.name
    [self-setName:name]
    相同,而不是
    self->name
    @特洛伊木马。如果正确,这是我说的,我将进行编辑以使其更清晰,因此在这两种情况下,我都在相同的变量上操作(也就是说,与我在内存中分配的位置相同)?@MrBr正确,您的两个示例都直接访问ivar。使用self.myProperty=…的区别在于您得到了合成的setter(假设您没有重写它们)这意味着您可以在非ARC环境中进行内存管理,以及其他类似KVO Notifications的功能。感谢您对第一部分的解释。我不明白您为什么在setter中保留
    name
    对象。我想我只需要在set中使用
    name
    对象在我将它分配给实例变量
    \u name
    之后,它可以被释放,而
    \u name
    应该保留以供以后使用?@MrBr这一切都取决于您是否使用了自动引用计数(ARC)。如果是这样,您就不必担心,您的版本也会很好。