Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

objective c - What equivalent code is synthesized for a declared property?

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
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...