“财产由 ivar 支持"?这在技术上意味着什么? [英] "property is backed by an ivar" ? What technically does that mean?

查看:59
本文介绍了“财产由 ivar 支持"?这在技术上意味着什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以......我对Objective C还是很陌生......拿一些iTunes U corses......做一些练习......

So ... I'm still fairly new to Objective C ... taking some iTunes U corses ... doing some exercises and all ...

但是当你使用@synthesize myProperty = _myIvarPropertyNameToUse;... iOS 5 会创建一个 ivar 来支持"该属性.

But when you uses to do @synthesize myProperty = _myIvarPropertyNameToUse; ... iOS 5 would create an ivar that would "back" the property.

就事物在内存中的位置而言,这里究竟发生了什么......

What exactly is going on here as far as where things sit in memory ...

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

(1) Is the ivar a true variable? ... or is it a pointer to the location of the property in the object?

(2) 属性在堆上,(作为对象的一部分),对吗?堆上的 ivar 也是这样吗?

(2) The property is on the heap, (being part of the object), right? Is the ivar on the heap as well?

我想我可能会失去全局……拥有由 ivar 支持的财产有什么意义?

I think I may be losing the big picture ... what's the point of having a property backed by an ivar?

谢谢,

推荐答案

Objective-C 对象只是在堆上分配的 C 结构体(或多或少).当您声明一个实例变量 (ivar) 时,它被定义为该结构的偏移量.因此,如果您像这样手动声明了一些 ivars(不要再这样做了,但它说明了这一点):

An Objective-C object is just a C struct that is allocated on the heap (well, more or less). When you declare an instance variable (ivar), it is defined as an offset into that struct. So if you manually declared some ivars like this (don't do it this way anymore, but it illustrates the point):

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

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

Then when you +alloc a new instance (call it foo), the struct will be some header followed by the ivars of NSObject followed by memory for ivar1 followed by memory for ivar2. ivar1 will be the foo point plus some offset. (This isn't exactly true anymore, but stay with me; it's simpler to understand the old implementation.)

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

Since foo is a pointer to a struct, you can actually refer directly to this offset pointer as foo->ivar1. It really is a struct. Never do this, but it is legal syntax.

@implementation 块内,ivar1 会自动转换为 self->ivar1.不要太担心 self 是如何实现的,但请相信它是指向您的结构的指针.同样,永远不要使用这种 -> 语法.这是一个底层实现细节(不再总是可能的;见下文).

Inside of the @implementation block, ivar1 is automatically translated to self->ivar1. Don't worry too much about how self is implemented, but trust that it's a pointer to your struct. Again, never use this -> syntax. It's an underlying implementation detail (and isn't always possible anymore; see below).

好的,这就是 ivar.在过去(ObjC 1.0),这实际上就是我们所拥有的.你声明了你的 ivars,然后你手工创建了访问器方法来设置和返回它们的值.

OK, so that's what an ivar is. In the old days (ObjC 1.0), that's actually all we had. You declared your ivars, and then you hand-created accessor methods that would set and return their values.

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

Then ObjC2 comes along, which in some cases also gave us something called the non-fragile ABI. That changes the underlying implementation of ivars somewhat, so you can't always actually use -> anymore. But you shouldn't have been using it anyway. Even so, it's simpler to pretend things are the old way. More to the point, ObjC2 added this new thing called "properties." A property is just a promise to implement certain methods. So when you say:

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

这几乎等同于以下内容:

this is almost identical to saying the following:

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

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

(The difference is very seldom important.) Note that this doesn't provide an implementation. It doesn't create ivars. It just declares some methods.

现在在 ObjC1 中,我们一遍又一遍地编写相同的访问器代码.你有 20 个可写的变量,你写了 40 个访问器方法.而且它们几乎一模一样.很多机会搞砸.和很多乏味.谢天谢地 Accessorizer.

Now in ObjC1, we wrote the same accessor code over and over and over again. You had 20 writable ivars, you wrote 40 accessor methods. And they were almost identical. Lots of opportunities to mess up. And a lot of tedium. Thank goodness for Accessorizer.

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

With ObjC2, the compiler would give you the most common implementation for free if you added @synthesize. It would automatically make an ivar with the same name as the property, and write a getter and (if needed) setter to read and write that ivar. Passing =_property just changes the name of the ivar used. We call this the "backing ivar."

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

Now, in the latest version of the compiler, you don't even need @synthesize. This pattern is so insanely common, and has been for decades, that it is now the default unless you tell the compiler not to do it. And it automatically synthesizes an ivar with a leading underscore (which is best practice).

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

The one other piece of information you should know is that you should always use the accessor to access the ivar, even inside of the object. The only exceptions are in the init and dealloc methods. There you should directly access the ivar (using the leading underscore).

这篇关于“财产由 ivar 支持"?这在技术上意味着什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆