self.ivar和伊娃之间的区别?
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"
之间的区别吗? 谢谢!
编辑:后续问题: 如何写一个伊娃自己的二传手,即:self.ivar = …?
注意,这个帖子是老的!
这篇文章是从前十年。
一定要读下面的重要脚注,欢呼!
当你刚开始时,真的很难理解这一切。
这里有一些简单,实用的经验法则的开始。
重复一遍,这篇文章是FOR BEGINNERS 。
这里的目标是让您快速从起跑线移动到能够在大多数情况下自信地使用该系统。
之后 ,你可以真正了解这些问题的内部运作。
(1)永远不要说name=@"hello"
。 总是说 self.name=@"hello"
。 做一个项目范围的name
搜索,并确保你总是说self.name
而不是name
,当你设置或改变它。
(2)你知道所有关于内存管理,初始化,释放等的令人生气的东西。 如果你使用自己的东西, 它会照顾你所有的 。 很酷吧?
(3)自我感觉特别有用,因为当你走的时候,你可以很容易地“改变”字符串 (或其它)。 所以,这样做完全可以,
self.name=@"aa"; self.name=@"bb"; self.name=@"cc";
而(一句话), 你永远不能,因为任何原因,这样做 …
name=@"aa"; name=@"bb"; name=@"cc";
(*)关于你的字面问题,“请解释name = @"hello"
和self.name = @"hello"?"
之间的区别self.name = @"hello"?"
这很容易做到。
第一个只是设置一个变量 。 你知道,就像生活简单,我们13岁时的"x=42"
一样。
第二个是完全不同的,特别是它叫一个复杂的例程 (称为“二传手”)为你做了很多惊人的和令人惊讶的东西。
所以这是你的问题的字面答案。 第一个只是设置变量 (不要忘了,有很多指针和其他奇怪的东西,作为一个规则,你当然不能只是像这样设置指针)。 第二个实际上是一个复杂的例程 ,因此为你做了很多事情。
第二个就像是说…
[name bigComplicatedRoutineHere:@"hello"];
…总是记住自己的语法是非常有帮助的self. ...
self. ...
实际上是调用一个例程 。
事实上,这个主题的一些思想家认为,当他们引入这个self.X
语法来表示[X complicatedThingHere]
时,这是一个愚蠢的想法。 它引起了很多混乱, 每个初学者都问你到底在问什么 。
就我个人而言,花了我九年时间才清楚这一点。 :-)所以我再强调一下,你必须记住,当你说self.x
,实际上, 你实际上正在调用一个例程 。
重复一遍:实际上,“自我点”语法调用一个例程。 (的确,我相信其中一个预处理器只是将其扩展到[x amazingStuffHere]
。)
我试图用一种方式来回答问题,让你学习内存管理,属性等等,让你提前使用更多的功能。 如果你比这篇文章更高级,只要忽略它。
请注意,这篇文章的目的是为初学者提供建议,使他们继续前进,不被激怒 。 希望它有帮助!
2014更新! ARC初学者重要注意事项…
注意,这个帖子现在已经五年了! 它已经被成千上万的初学者阅读,并且有很多后续问题等。请注意,今天在新的“ARC世界”。 在某种程度上:如果你是一个初学者:你应该几乎只使用! 属性。 即随时随地使用“self.whatever”。 无论如何,只要知道这篇文章中的信息是“很有历史意义的”,而且每天都变得更加如此。 当然,不言而喻,一旦你是一个专家,你将需要并将理解这一切的每一个微妙的细节。 希望它可以帮助别人。
self.name
使用由您定义的访问器和/或增变器(这是非原子的并保留在您的案例中)。 所以当你调用self.name = foo
,它会调用编译器生成的setName:(NSString *)str
mutator,它将首先释放当前字符串,然后保留新字符串,并最终将名称设置为保留字符串。
只要调用name = foo
就可以为foo分配名称。
这也意味着你只能在为伊娃定义一个属性时才能调用self.xxx
,否则编译器会告诉你它并不知道它(iVar)。
名字= @“乔”
你直接访问这个变量,绕过了Cocoa为你创建的getter方法。 通常,不是最明智的做法。
self.name = @“Joe”
现在你通过你问可可为你创造的方法。 这通常是最好的方法。
作为一个经验法则,总是使用Cocoa提供的setter和getter,但有一个例外:dealloc。 在dealloc中,你应该总是直接释放变量,而不是通过getter方法:
-(void) dealloc { [name release]; // instead of [[self name] release] ... [super dealloc]; }
在dealloc中避免访问者的原因是,如果在子类中有观察者或重写触发行为,它将从dealloc触发,这几乎不是你想要的(因为对象的状态将不一致)。
OTOH,还有一个更方便的声明iVars的语法,你可能不知道。 如果您只定位到64位mac,则可以使用属性来生成存取方法和实例变量本身:
#import <Cocoa/Cocoa.h> @interface Photo : NSObject @property (retain) NSString* caption; @property (retain) NSString* photographer; @end
这是真正的内存管理,属性语法是真正的setter和getter方法,使用self.xxx =?时,可以调用setter方法,对象保留cout +1,名称不能释放,但是如果name = foo是没有关于财产语法。
setter方法的例子:
-(void)setObj:(ClassX*) value { if (obj != value) { [obj release]; obj = [value retain]; } }