代码之家  ›  专栏  ›  技术社区  ›  ohho

self.ivar和ivar之间的区别?

  •  39
  • ohho  · 技术社区  · 14 年前
    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 = ...?

    4 回复  |  直到 14 年前
        1
  •  64
  •   Fattie    9 年前

    注意,这篇文章很旧!

    这篇文章来自前十年。

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


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

    以下是一些简单实用的经验法则 对于初学者 .

    重复一下,这篇文章是 对于初学者

    这里的目的是让你 迅速地 从起点出发,在大多数情况下都能自信地使用系统。

    以后 您可以真正了解这些问题的内部工作原理。

    (1)不要说 name=@"hello" 总是说 self.name=@"hello" . 在项目范围内搜索 name 确保你总是说 self.name 而不是 名称 ,设置或更改时。

    (2)你知道关于内存管理、初始化、释放等所有让人恼火的事情。如果你使用自我意识, 它会帮你解决所有的问题 . 酷啊?

    (3)自我思考特别有用,因为你可以 轻松“更改”字符串 (或不管是什么)随着你的前进。所以,这样做完全没关系,

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

    鉴于(一句话) 你永远不能,永远,无论如何,这样做

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

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

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

    第二个完全不同,具体来说 这叫一个复杂的程序 (被称为“二传手”)为你做了很多惊人的事情。

    这就是你问题的字面答案。 第一个只设置变量 (别忘了,这里有很多指针和其他奇怪的东西,通常你肯定 不能 只是随意地设置指针。 第二个程序实际上称为一个复杂的程序 因此你要做很多事情。

    再一次,第二个就是说…

    [name bigComplicatedRoutineHere:@"hello"];
    

    …记住语法是非常有用的 self. ... 字面上说是例行程序

    事实上,一些关于这个话题的思想家在介绍这个问题时认为这是一个愚蠢的想法。 self.X 要表示的语法 [X complicatedThingHere] . 它引入了很多困惑,以及 每个初学者都会问你到底在问什么 .

    就我个人而言,我花了九年多的时间才明白这一点。:-)因此,我再次强调,当你说 self.x 实际上, 你实际上是在叫一个程序

    重复:“self-dot”语法实际上调用了一个例程。(事实上,我相信其中一个预处理器只是把它扩展到 [x amazingStuffHere] )

    我试着用一种能让你继续前进的方式来回答问题,让你在学习内存管理、属性等等的时候,能够前进并使用更多的功能。如果你比这篇文章更高级,就忽略它。

    请注意,这篇文章是给初学者的建议 使他们能够 继续前进,不要被激怒 . 希望有帮助!


    2014年更新!关于初学者弧线的重要提示…

    注意,这篇文章是 5岁 现在!它已经被成千上万的初学者阅读,有很多后续问题等。请注意,今天在新的“ARC世界”。在某种程度上:如果你是一个初学者:你应该 只使用!! 属性。也就是说,无论何时何地,都要使用“自我”。无论如何,只要知道这篇文章中的信息“基本上是历史性的”,而且每天都在变得越来越重要。当然,毫无疑问,一旦你是一个专家,你将需要并将理解所有这些微妙的细节。希望它能帮助别人。

        2
  •  32
  •   triandicAnt    10 年前

    self.name 使用您定义的访问器和/或赋值器(这是非原子的,在您的情况下保留)。所以当你打电话的时候 self.name = foo ,它将调用 setName:(NSString *)str 由编译器生成的赋值函数,它首先释放当前字符串,然后保留新字符串,最后将名称设置为保留的字符串。

    只是打电话 name = foo 只为foo分配名称。

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

        3
  •  6
  •   jlehr    12 年前

    name=@“乔”

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

    self.name=@“乔”

    现在,你要通过你要求可可为你创造的方法。这通常是最好的方法。

    根据经验,总是使用cocoa提供的setter和getter,但有一个例外:dealoc。在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
    
        4
  •  -2
  •   Lee    11 年前

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

    setter方法示例:

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