【问题标题】:Difference between self.ivar and ivar?self.ivar 和 ivar 之间的区别?
【发布时间】:2011-05-07 17:31:51
【问题描述】:
aclass.h

@interface aClass : NSObject {
    NSString *name;
}

@property (nonatomic, retain) IBOutlet NSString *name;

@end

aclass.m 

@implementation aClass

@synthesize name;

- (void)dealloc {
    [name release];
    [super dealloc];    
}

- (void)test1 {
    name = @"hello";
}

- (void)test2 {
    self.name = @"hello";
}

以上面为例。有人可以解释name = @"hello"self.name = @"hello" 之间的区别吗?谢谢!

编辑:后续问题:How to write my own setter for an ivar, i.e.: self.ivar = ...?

【问题讨论】:

标签: iphone objective-c ios


【解决方案1】:

请注意,这篇文章已经过时了!

这篇文章是过去十年的。

请务必阅读下面的重要脚注,干杯!!


当你刚刚开始的时候,真的很难理解这一切。

这里有一些简单实用的经验法则适合初学者

重复一遍,这篇文章适合初学者

这里的目的是让您快速从起跑线开始,在大多数情况下都能自信地使用系统。

稍后,您可以真正了解这些问题的内部运作。

(1) 永远不要说name=@"hello"总是说 self.name=@"hello"。在项目范围内搜索 name 并确保在设置或更改时始终使用 self.name 而不是 name

(2) 你知道所有关于内存管理、初始化、释放等令人生气的东西。如果您使用 self thingy,它会为您处理所有这些。很酷吧?

(3) self thingy 特别有用,因为您可以轻松“更改”字符串(或其他任何内容)。所以,这样做完全没问题,

self.name=@"aa";  
self.name=@"bb";  
self.name=@"cc";  

而(总而言之)无论出于何种原因,您永远都不能这样做...

name=@"aa";
name=@"bb";
name=@"cc";

( * ) 关于你的字面问题,“请解释name = @"hello"self.name = @"hello"?" 之间的区别,这很容易做到。

第一个是只是设置一个变量。你知道的,就像过去我们 13 岁时生活简单的 "x=42"

第二个完全不同,特别是它调用一个复杂的例程(称为“setter”)为你做很多令人惊奇的事情。

这就是你问题的字面答案。 第一个只是设置变量(别忘了,其中涉及到很多指针和其他奇怪的东西,通常你当然不能只是像那样随意设置指针)。 第二个实际上调用了一个大而复杂的例程,因此为您做了很多事情。

再一次,第二个就像在说……

[name bigComplicatedRoutineHere:@"hello"];

...始终记住语法self. ... 实际上是调用例程非常有帮助。

确实,当他们将这种self.X 语法引入到[X complicatedThingHere] 时,该主题的一些思想家认为这是一个愚蠢的想法。这会带来很多困惑,并且每个初学者都会确切地问你在问什么

就我个人而言,我花了九年多的时间才把这一点弄清楚。 :-) 所以,我再次强调,你必须记住,当你说self.x 时,实际上,你实际上是在调用一个例程

重复一遍:“自点”语法实际上调用了一个例程。 (事实上​​,我相信其中一个预处理器只是将其扩展为[x amazingStuffHere]。)

我试图以一种能让您继续前进并允许您在学习内存管理、属性等的同时推进和使用更多功能的方式来回答。如果你比这篇文章更高级,请忽略它。

请注意,这篇文章旨在为初学者提供建议,让他们继续前进,不要被激怒。希望对您有所帮助!


2014 年更新! ARC 初学者注意事项...

注意,这篇文章已经 5 岁了了!它已被成千上万的初学者阅读,并且有许多后续问题等。请注意,今天在新的“ARC世界”中。在某种程度上:如果你是初学者:你应该只使用!!属性。即,随时随地使用“self.whatever”。无论如何,请注意,这篇文章中的信息“很大程度上是历史性的”,而且每天都在变得越来越重要。当然,不用说,一旦您成为专家,您将需要并且将了解这一切的每一个微妙细节。希望它可以帮助某人。

【讨论】:

  • “你知道所有关于内存管理、初始化、释放等令人生气的东西。如果你使用 self 的东西,它会为你处理所有这些。” - 这是一个危险的说法。这也是错误的。它不会为你处理它。您仍然有责任在某些时候释放该对象,您仍然需要始终了解它的所有权。
  • 嗨,乔,非常感谢您的回答。我可以解释为:name = @"hello" 仅将@"hello" 的指针分配给name,当@"hello" 超出范围时,name 指向一些垃圾;相反,self.name = @"hello" 将在内存中保留(副本/克隆)@"hello",即 1) +1 for @"hello" 2) -1 for name 3) 将 @"hello" 的指针分配给 @987654348 @
  • 这会让你陷入困境,因为我刚刚发现了整个周末,我们大多数人都习惯于来自老派背景,x=whatever 并且随处可见。
【解决方案2】:

self.name 使用您定义的访问器和/或修改器(这是非原子的,在您的情况下保留)。所以当你调用self.name = foo时,它会调用编译器生成的setName:(NSString *)str mutator,它会先释放当前字符串,然后保留新的字符串,最后将name设置为保留的字符串。

只是调用name = foo 只不过是为 foo 分配名称。

这也意味着当你为 ivar 定义了一个属性时,你只能调用self.xxx,否则编译器会告诉你它不知道它(iVar)。

【讨论】:

    【解决方案3】:

    真正的内存管理,首先属性语法是真正的setter和getter方法,当使用self.xxx = ?时,可以调用setter方法,对象retain cout +1,name不能释放,但是如果name = foo 与属性语法无关。

    setter 方法示例:

    -(void)setObj:(ClassX*) value 
    {  
             if (obj != value) 
             { 
                       [obj release]; 
                       obj = [value retain]; 
             } 
    } 
    

    【讨论】:

      【解决方案4】:

      name = @"乔"

      您直接访问变量,绕过了 Cocoa 为您创建的 getter 方法。通常,这不是最明智的做法。

      self.name = @"乔"

      现在您正在执行您要求可可为您创建的方法。这通常是最好的方法。

      根据经验,始终使用 Cocoa 提供的 setter 和 getter,只有一个例外:dealloc。在 dealloc 中,您应该始终直接释放变量,而不是通过 getter 方法:

      -(void) dealloc {
         [name release]; // instead of [[self name] release]
         ...
      
         [super dealloc];
      }
      

      避免在 dealloc 中使用访问器的原因是,如果在触发行为的子类中有观察者或覆盖,它将从 dealloc 触发,这几乎不是您想要的(因为对象的状态将是不一致)。

      OTOH,还有一种更方便的语法来声明您可能不知道的 iVar。如果您只针对 64 位 mac,您可以使用属性来生成访问器方法和实例变量本身:

      #import <Cocoa/Cocoa.h>
      @interface Photo : NSObject 
      @property (retain) NSString* caption; 
      @property (retain) NSString* photographer; 
      @end
      

      【讨论】:

      • 您说“您可以使用属性来生成访问器方法和实例变量本身”,但您给出的示例仅显示属性声明,两者都不做。您需要@synthesize 来合成访问器方法和/或实例变量。
      猜你喜欢
      • 2023-03-09
      • 1970-01-01
      • 2012-10-08
      • 2011-07-30
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 2020-05-10
      • 2014-09-20
      相关资源
      最近更新 更多