“财产由伊娃支持”?这在技术上意味着什么?

时间:2012-10-15 15:50:29

标签: objective-c properties ivar

所以...我仍然是Objective C的新手...拿一些iTunes U corses ...做一些练习和所有......

但是当你用来做@synthesize myProperty = _myIvarPropertyNameToUse时; ... iOS 5将创建一个“后退”属性的ivar。

到目前为止记忆中的内容究竟是什么......

(1)ivar是真正的变量吗? ...或者它是指向对象中属性位置的指针吗?

(2)属性在堆上,(作为对象的一部分),对吧?伊娃是否也在堆上?

我想我可能会失去一个大局......拥有一个由伊瓦尔支持的房产有什么意义?

感谢,

2 个答案:

答案 0 :(得分:13)

Objective-C对象只是一个在堆上分配的C结构(好吧,或多或少)。声明实例变量(ivar)时,它被定义为该结构的偏移量。所以如果你手动宣布这样的一些ivars(不要这样做了,但它说明了这一点):

@interface Foo : NSObject {
   NSString *ivar1;
   NSString *ivar2;
}

然后当你+alloc一个新实例(称之为foo)时,结构将是一些标题,后跟NSObject的ivars,后跟ivar1的内存,后跟ivar2的内存{1}}。 ivar1将是foo点加上一些偏移量。 (这不完全正确,但请留在我身边;理解旧的实现更简单。)

由于foo是指向结构的指针,因此您实际上可以直接将此偏移指针引用为foo->ivar1。它确实是一个结构。永远不要这样做,但它是合法的语法。

@implementation区块内,ivar1会自动翻译为self->ivar1。不要过分担心如何实现self,但要相信它是指向结构的指针。同样,永远不要使用此->语法。这是一个底层的实现细节(并不总是可能的;见下文)。

好的,这就是伊娃的意思。在过去(ObjC 1.0),这实际上就是我们所拥有的一切。你声明了你的ivars,然后你手工创建了可以设置和返回它们的值的访问器方法。

然后ObjC2出现了,在某些情况下也给了我们一些叫做非脆弱的ABI。这在某种程度上改变了ivars的底层实现,因此您不能总是实际使用->。但你无论如何都不应该使用它。即便如此,假装事物是旧的方式也更简单。更重要的是,ObjC2添加了一个名为“属性”的新东西。属性只是实现某些方法的承诺。所以当你说:

@property (nonatomic, readwrite, strong) NSString *property;

这几乎与以下内容相同:

- (NSString *)property;
- (void)setProperty:(NSString *)aProperty;

(差异很少很重要。)请注意,这不提供实现。它不会创造伊娃。它只是声明了一些方法。

现在在ObjC1中,我们一遍又一遍地编写了相同的访问者代码。你有20个可写的ivars,你写了40个访问方法。它们几乎相同。很多机会搞砸了。而且很多单调乏味。谢天谢地Accessorizer

使用ObjC2,如果添加@synthesize,编译器会免费为您提供最常见的实现。它将自动生成一个与属性同名的ivar,并编写一个getter和(如果需要)setter来读取和写入该ivar。传递=_property只会更改所用ivar的名称。我们称之为“支持ivar。”

现在,在最新版本的编译器中,您甚至不需要@synthesize。这种模式非常普遍,并且已经存在了几十年,现在它是默认模式,除非你告诉编译器不要这样做。它会自动合成一个带有前导下划线的ivar(这是最佳实践)。

您应该知道的另一条信息是,您应该始终使用访问器来访问ivar,甚至是在对象内部。唯一的例外是initdealloc方法。在那里你应该直接访问ivar(使用前导下划线)。

答案 1 :(得分:0)

为了清楚起见,当你@synthesize myProperty = _myIvarPropertyNameToUse;时,你只能更改支持ivar的名称。行@synthesize myProperty;也会创建一个支持ivar,但它将被称为myProperty,而不是_myIvarPropertyNameToUse ...

支持ivar是对象的一部分,所以是的,它在堆上。它可以用作真正的变量,这意味着您可以在目标代码中获取和设置它。