self.ivar和ivar之间的区别?

ohh*_*hho 39 iphone objective-c ios

aclass.h

@interface aClass : NSObject {
    NSString *name;
}

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

@end
Run Code Online (Sandbox Code Playgroud)
aclass.m 

@implementation aClass

@synthesize name;

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

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

- (void)test2 {
    self.name = @"hello";
}
Run Code Online (Sandbox Code Playgroud)

以上面为例.可能有人请解释之间的差异name = @"hello"self.name = @"hello"?谢谢!

编辑:后续问题:如何为ivar编写我自己的setter,即:self.ivar = ...?

Fat*_*tie 64

请注意,这个帖子已经老了!

这篇文章来自前十年.

请务必阅读下面的重要脚注,欢呼!


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

以下是一些简单,实用的经验法则FOR BEGINNERS.

重复一下,这篇文章是FOR BEGINNERS.

这里的目的是让您快速从起跑线移动到能够在大多数情况下自信地使用系统.

之后,您可以真正了解这些问题的内部运作方式.

(1)不要说name=@"hello".总是说 self.name=@"hello".做一个项目范围内的搜索name,并确保你总是说self.name,不name,当你对它进行设置或更改.

(2)你知道关于内存管理,初始化,发布等所有令人生气的事情.如果你使用自己的东西,它会照顾你的一切.好吧?

(3)自我特别有用,因为你可以轻松地"改变"字符串(或其他任何东西).所以,这样做完全没问题,

self.name=@"aa";  
self.name=@"bb";  
self.name=@"cc";  
Run Code Online (Sandbox Code Playgroud)

而(总之)你永远不会,出于任何理由,这样做 ......

name=@"aa";
name=@"bb";
name=@"cc";
Run Code Online (Sandbox Code Playgroud)

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

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

第二个是完全不同的,特别是它调用一个复杂的例程(称为"setter")为你做了许多令人惊讶和惊人的事情.

这就是你问题的字面答案.第一个只是设置变量(并且不要忘记,有很多指针和其他奇怪的东西涉及,并且作为一个规则,你当然不能像这样无情地设置指针). 第二个实际上是一个复杂的例程,因此为你做了很多事情.

再一次,第二个就像说......

[name bigComplicatedRoutineHere:@"hello"];
Run Code Online (Sandbox Code Playgroud)

...总是记住语法self. ... 是字面上调用例程是非常有帮助的.

实际上,一些有关该主题的思想家认为,当他们引入这种self.X语法时,这是一个愚蠢的想法[X complicatedThingHere].它引起了很多混乱,每个初学者都会问你究竟在问什么.

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

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

我试图以一种让你继续前进并允许你推进和使用更多功能的方式回答,同时你了解内存管理,属性等等.如果你比这篇文章更先进,那就忽略它.

请注意,这篇文章旨在为初学者提供建议,使他们能够继续前进而不会被激怒.希望能帮助到你!


2014年更新!关于ARC的初学者重要提示......

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

  • "你知道关于内存管理,初始化,发布等所有令人生气的事情.如果你使用自己的东西,它会为你完成所有这些." - 这是一个危险的要求.这也是错的.它不会照顾你.您仍然有责任在某个时间释放该对象,您仍然需要始终了解其所有权. (4认同)

Jus*_*Sid 32

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

只是调用name = foo只是为foo分配名称.

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


cfi*_*her 6

name = @"Joe"

您正在直接访问变量,绕过Cocoa为您创建麻烦的getter方法.通常,这不是最明智的事情.

self.name = @"乔"

现在,您将通过您要求可可为您创建的方法.这通常是最好的方法.

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

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

   [super dealloc];
}
Run Code Online (Sandbox Code Playgroud)

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

OTOH,还有一个稍微方便的语法来声明你可能不知道的iVars.如果您只定位64位mac,则可以使用属性生成访问器方法和实例变量本身:

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