为声明的属性合成了哪些等效代码? [英] What equivalent code is synthesized for a declared property?
问题描述
getter 和 setter 方法主体在自动合成后究竟是什么样子的?
How exactly getter and setter methods body looks like after they have been automatically synthesized ?
从官方文档中我发现到目前为止只有推荐的实现技术,但是没有关于编译器在合成过程中使用哪些技术的消息:http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539-SW5
From official documentation I found so far only recommended implementation techniques, however no word about which of them used by compiler during synthesizing process: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539-SW5
某些技术推荐包含 autorelease
消息的实现,这对于多线程编程来说不是很安全.我只是想知道自动生成的代码是否遵循一些建议的实现.
Some techniques recommends implementations containing autorelease
message, which is not quite secure for multithreaded programming. I'm just wonder if auto-generated code follows to some of the proposed implementations.
例如:
.h
@interface AClass: NSObject{}
@property (nonatomic, retain) AnotherClass *aProp;
@end
.m
@implementation AClass
@synthesize aProp
-(id) init {
if ((self = [super init])) {
self.aProp = [[AnotherClass alloc] init]; // setter invocation
}
return self;
}
-(AnotherClass *) aMethod {
return self.aProp; // getter invocation
}
@end
编译器生成的 aProp
的等效访问器代码片段是什么?
What are equivalent accessors code snippets for aProp
generated by compiler ?
-(AnotherClass *) aProp {
// getter body
}
-(void) setAProp: (AnotherClass *) {
// setter body
}
推荐答案
将属性声明为 nonatomic
时,您将得到以下内容:
When declaring a property as nonatomic
, you'll get the following:
// .h
@property (nonatomic, retain) id ivar;
// .m
- (id)ivar {
return ivar;
}
- (void)setIvar:(id)newValue {
if (ivar != newValue) { // this check is mandatory
[ivar release];
ivar = [newValue retain];
}
}
注意检查 ivar != newValue
.如果不存在,ivar 可以在 release
之后被释放,并且下面的 retain
会导致内存访问错误.
Note the check ivar != newValue
. If it was absent, ivar could be dealloc'ed after release
, and the following retain
would cause a memory access error.
当您使用 copy
声明您的属性时,代码看起来几乎相同,只是将 retain
替换为 copy
.
When you declare your property with copy
, the code will look almost the same, with retain
replaced by copy
.
对于assign
,就更简单了:
- (void)setIvar:(id)newValue {
ivar = newValue;
}
<小时>
现在,当您将属性声明为 atomic
(这是默认值)时,事情会变得稍微复杂一些.Apple 的一位工程师在开发论坛上发布了一段与下面类似的片段:
Now, when you declare your property as atomic
(this one is the default), things get slightly more complicated. A snippet similar to the one below was posted by one of Apple's engineers on the development forums:
- (id)ivar {
@synchronized (self) {
return [[self->ivar retain] autorelease];
}
}
- (void)setIvar:(id)newValue {
@synchronized (self) {
if (newValue != self->ivar) {
[self->ivar release];
self->ivar = newValue;
[self->ivar retain];
}
}
}
注意两个方法中的 @synchronized
块和 getter 中的附加 retain-autorelease
.这两件事都确保您将获得先前的值(保留和自动释放)或新的值,以防在您尝试读取它时某个线程更改了该值.
Note the @synchronized
block in both methods and additional retain-autorelease
in the getter. Both those things ensure that you will either get the previous value (retained and autoreleased) or a new one in the case the value is changed by some thread while you are trying to read it.
这篇关于为声明的属性合成了哪些等效代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!