Objective-C中的ivars和属性之间有什么区别?

在objective-c中使用ivars和属性的三种方法之间的语义差异是什么?

1。

@class MyOtherObject; @interface MyObject { } @property (nonatomic, retain) MyOtherObject *otherObj; 

2。

 #import "MyOtherObject.h" @interface MyObject { MyOtherObject *otherObj; } @property (nonatomic, retain) MyOtherObject *otherObj; 

3。

  #import "MyOtherObject.h" @interface MyObject { MyOtherObject *otherObj; } 

Number 1与另外两个不同之处在于,通过向前声明MyOtherObject类来最大限度地减less编译器和链接器所看到的代码量,并且还可能避免循环引用。 如果你这样做,记得把#import放到.m文件中。

通过声明@property(和.m中匹配的@synthesize)文件,你可以自动生成存储器语义的访问器方法来处理你指定的方式。 大多数对象的经验法则是保留,但NSStrings,例如应该使用复制。 单身人士和代表通常应该使用分配。 手写访问器是乏味和容易出错的,所以这节省了大量的input和愚蠢的错误。

另外,声明一个综合属性可以让你使用点符号来调用访问器方法,如下所示:

 self.otherObj = someOtherNewObject; // set it MyOtherObject *thingee = self.otherObj; // get it 

而不是正常的消息传递方式:

 [self setOtherObject:someOtherNewObject]; // set it MyOtherObject *thingee = [self otherObj]; // get it 

在幕后你真的调用了一个如下所示的方法:

 - (void) setOtherObj:(MyOtherObject *)anOtherObject { if (otherObject == anOtherObject) { return; } MyOtherObject *oldOtherObject = otherObject; // keep a reference to the old value for a second otherObject = [anOtherObject retain]; // put the new value in [oldOtherObject release]; // let go of the old object } // set it 

…或这个

 - (MyOtherObject *) otherObject { return otherObject; } // get it 

屁股总疼痛,对。 现在就为class上的每个伊维尔做那个。 如果你没有做到完全正确,你会得到一个内存泄漏。 最好让编译器完成这个工作。

我看到第一号没有伊娃。 假设这不是一个错字,那么没关系,因为@property / @synthesize指令会在幕后为你声明一个ivar。 我相信这是Mac OS X Snow Leopard和iOS4的新function。

编号3没有生成访问者,所以你必须自己写。 如果你想要你的访问器方法有副作用,那么你要做标准的内存pipe理跳舞,如上所示,然后在访问器方法内部做所有你需要的工作。 如果你综合了一个属性并编写你自己的属性,那么你的版本有优先权。

我覆盖了一切吗?

回到过去,你有ivars,如果你想让别的类设置或读取它们,那么你必须定义一个getter(即-(NSString *)foo)和setter(即-(void)setFoo:(NSString *)aFoo; )。

什么属性给你是一个免费(几乎!)与伊娃一起的二传手和吸气。 所以当你现在定义一个属性的时候,你可以设置primefaces性(例如,是否允许来自多个线程的多个设置动作)以及赋值/保留/复制语义(也就是说,设置者是否应该复制新值或者只保存当前值 – 如果另一个类试图使用可变string设置string属性,那么以后可能会更改)。

这是@synthesize所做的。 很多人离开伊娃的名字是一样的,但是当你写综合语句时你可以改变它(即@synthesize foo=_foo;意思是为属性foo创build一个名为_foo的伊娃,所以如果你想读或写这个属性而且你不使用self.foo ,你将不得不使用_foo = ... – 它只是帮助你直接引用伊娃,如果你只想通过setter和getter)。

从Xcode 4.6开始,你不需要使用@synthesize语句 – 编译器会自动执行它,默认情况下,会在_ar上添加ivar的名字。