所以...我仍然是Objective C的新手...拿一些iTunes U corses ...做一些练习和所有......
但是当你用来做@synthesize myProperty = _myIvarPropertyNameToUse时; ... iOS 5将创建一个“后退”属性的ivar。
到目前为止记忆中的内容究竟是什么......
(1)ivar是真正的变量吗? ...或者它是指向对象中属性位置的指针吗?
(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,甚至是在对象内部。唯一的例外是init
和dealloc
方法。在那里你应该直接访问ivar(使用前导下划线)。
答案 1 :(得分:0)
为了清楚起见,当你@synthesize myProperty = _myIvarPropertyNameToUse;
时,你只能更改支持ivar的名称。行@synthesize myProperty;
也会创建一个支持ivar,但它将被称为myProperty,而不是_myIvarPropertyNameToUse ...
支持ivar是对象的一部分,所以是的,它在堆上。它可以用作真正的变量,这意味着您可以在目标代码中获取和设置它。