为声明的属性合成了什么等效代码?

Mar*_*aev 3 gcc memory-management objective-c

在自动合成后,getter和setter方法的主体是什么样的?

从官方文档到目前为止我发现只推荐了实现技术,但是没有关于编译器在合成过程中使用哪些文件的说法: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
Run Code Online (Sandbox Code Playgroud)

.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
Run Code Online (Sandbox Code Playgroud)

什么是aProp编译器生成的等效访问者代码片段?

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

-(void) setAProp: (AnotherClass *) {
    // setter body
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*lik 8

在声明属性时nonatomic,您将获得以下内容:

// .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];
    }
}
Run Code Online (Sandbox Code Playgroud)

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

当您声明属性时copy,代码看起来几乎相同,retain替换为copy.

因为assign,它更简单:

- (void)setIvar:(id)newValue {
    ivar = newValue;
}
Run Code Online (Sandbox Code Playgroud)

现在,当您将属性声明为atomic(这是默认属性)时,事情变得稍微复杂一些.苹果公司的一位工程师在开发论坛上发布了一个与下面类似的片段:

- (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];
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意@synchronized两种方法中的块和retain-autoreleasegetter中的附加块.这两件事确保您在获得某个线程时尝试读取该值时,将获得之前的值(保留和自动释放)或新值.