为声明的属性合成了什么等效代码? [英] What equivalent code is synthesized for a declared property?

查看:90
本文介绍了为声明的属性合成了什么等效代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



在官方文档中,我发现迄今为止只有推荐的实现技术,但是没有关于编译器在合成过程中使用了哪些内容: http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html#//apple_ref/doc/uid/TP40003539-SW5



一些技术推荐包含 autorelease 消息的实现,这对于多线程编程来说不是很安全。我只是想知道自动生成的代码是否适用于某些提议的实现。






例如:



.h

  @interface AClass:NSObject {} 
@property(nonatomic,retain)AnotherClass * aProp;
@end

.m

  @implementation AClass 
@synthesize aProp

- (id)init {
if( = [super init])){
self.aProp = [[AnotherClass alloc] init]; // setter调用
}
return self;
}

- (AnotherClass *)aMethod {
返回self.aProp; // getter invocation
}
@end

什么是等价的访问器代码片段对于 aProp 由编译器生成?

   - (AnotherClass *)aProp { 
// getter body

$ b - (void)setAProp :( AnotherClass *){
// setter body
}


解决方案

当声明一个属性为 nonatomic
$ p $ // .h
@property(nonatomic,retain) id ivar;

// .m
- (id)ivar {
return ivar;

$ b $ - (void)setIvar:(id)newValue {
if(ivar!= newValue){//此检查是强制性的
[ivar release] ;
ivar = [newValue retain];


请注意检查 ivar! = newValue 。如果它不存在,ivar可以在 release 之后解除分配,并且下面的 retain 会导致内存访问错误。



当你用 copy 声明你的属性时,代码看起来几乎是一样的,用<$ c $ copy

,它更简单:

   - (void)setIvar:(id)newValue {
ivar = newValue;

code



$ b

现在,当你声明你的属性为 atomic (这是默认的),事情会变得稍微复杂一些。苹果的一位工程师在发展论坛上发布了一段类似于下面的代码片段:
$ b

   - (id)ivar {
@synchronized(self){
return [[self> ivar retain] autorelease];


$ b - (void)setIvar:(id)newValue {
@synchronized(self){
if(newValue!= self- > ivar){
[自主>伊娃发行];
自我> ivar = newValue;
[self> ivar retain];



$ / code $ / pre

注意 @synchronized 在这两个方法中都会阻塞,并且在getter中增加 retain-autorelease 。这两件事情确保你可以得到以前的值(保留和自动释放),或者在你尝试读取值时由某个线程改变值的情况下获得新值。


How exactly getter and setter methods body looks like after they have been automatically synthesized ?

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

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.


For example:

.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

What are equivalent accessors code snippets for aProp generated by compiler ?

-(AnotherClass *) aProp {
    // getter body
}

-(void) setAProp: (AnotherClass *) {
    // setter body
}

解决方案

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];
    }
}

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.

When you declare your property with copy, the code will look almost the same, with retain replaced by copy.

For assign, it is even simpler:

- (void)setIvar:(id)newValue {
    ivar = newValue;
}


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];
        }
    }
}

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屋!

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