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

时间:2011-03-18 10:17:49

标签: objective-c gcc memory-management

自动合成后,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

的.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的等效访问者代码片段是什么?

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

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

2 个答案:

答案 0 :(得分: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];
    }
}

请注意支票ivar != newValue。如果不存在,则可以在release之后取消分配ivar,并且以下retain将导致内存访问错误。

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

对于assign,它甚至更简单:

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

现在,当您将属性声明为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];
        }
    }
}

请注意两种方法中的@synchronized块和getter中的其他retain-autorelease。这两件事都可以确保您获得之前的值(保留和自动释放)或者在您尝试阅读时由某个线程更改值的情况下获得新值。

答案 1 :(得分:0)

这取决于您设置的属性,例如使用RETAIN属性...

- (void)setAProp:(AnotherClass *)value {
   [aProp release];
   aProp = value;
   [aProp retain];
}

对于ASSIGN属性....

- (void)setAProp:(AnotherClass *)value {
   aProp = value;
}

对于COPY属性(与NSString一起使用)......

- (void)setAProp:(AnotherClass *)value {
   aProp = [value copy];
}