Какой эквивалентный код синтезируется для объявленного свойства? - PullRequest
3 голосов
/ 18 марта 2011

Как выглядит тело методов 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 ]

8 голосов
/ 18 марта 2011

При объявлении свойства как 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.Если он отсутствует, ivar может быть освобожден после release, а следующее retain вызовет ошибку доступа к памяти.

Когда вы объявляете свойство с помощью copy, код будет выглядеть почтито же самое, с retain, замененным на copy.

Для assign, это еще проще:

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

Теперь, когда вы объявляете свою собственность как atomic (по умолчанию), все немного сложнее.Фрагмент, похожий на приведенный ниже, был опубликован одним из инженеров Apple на форумах разработчиков:

- (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 в обоих методах и дополнительный retain-autorelease в геттере.Обе эти вещи гарантируют, что вы получите либо предыдущее значение (сохраненное и автоматически освобожденное), либо новое в случае, если значение изменяется каким-либо потоком, пока вы пытаетесь его прочитать.

0 голосов
/ 18 марта 2011

Это зависит от установленных вами атрибутов, например с атрибутом 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];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...