Подтвердить что ты не робот

@property и @synthesize в objective-c

Пока я играл и выяснял, как все работает в https://github.com/enormego/EGOTableViewPullRefresh, я обнаружил таинственность @property и @synthesize. Вот код, который я упомянул

EGORefreshTableHeaderView.h

@interface EGORefreshTableHeaderView : UIView {
    id _delegate;
    EGOPullRefreshState _state;

    UILabel *_lastUpdatedLabel;
    UILabel *_statusLabel;
    CALayer *_arrowImage;
    UIActivityIndicatorView *_activityView;
}

@property(nonatomic,assign) id <EGORefreshTableHeaderDelegate> delegate;

EGORefreshTableHeaderView.m

@synthesize delegate=_delegate;

Я прочитал этот http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html и, насколько я понимаю, он создает новое имя для _delegate, которое является делегатом. (Правильно ли я с этим пониманием?)

Но я до сих пор не понимаю, почему они должны усложнять эту директиву @synthesize =.

4b9b3361

Ответ 1

Насколько это сложно, правда? Это всего лишь немного синтаксиса, который позволяет вам указать ivar, который вы хотите использовать, чтобы вернуть свойство, для которого вы говорите компилятору о создании аксессуаров. Если они не предоставили это или что-то подобное, тогда вам всегда нужно, чтобы ваши имена свойств соответствовали вашим именам ivar, и есть причины, по которым вы этого не хотите.

Если вам не нужно называть ваши ivars по-разному, вам не нужно беспокоиться о том, чтобы указать имя ivar. На самом деле вам не нужно создавать ivars вообще для ваших свойств... если вы этого не сделаете, компилятор создаст их для вас.

Обновление:. По состоянию на середину 2013 года LLVM по умолчанию использует синтез аксессуаров для свойств, поэтому в большинстве случаев вам больше не нужно указывать @synthesize вообще. Один случай, когда вы все равно будете использовать его, - это когда вы хотите вернуть свойство с другой переменной экземпляра, чем тот, который будет генерировать компилятор для вас. Кроме того, имя по умолчанию для ivar, которое поддерживает свойство, будет именем свойства с префиксом подчеркивания. Таким образом, код в примере OP можно упростить, удалив строки:

id _delegate;

и

@synthesize delegate=_delegate;

Я удалил свой предыдущий совет против использования префикса подчёркивания, поскольку он явно не согласен с текущим модом и поведением по умолчанию для компилятора. Однако, насколько мне известно, все еще плохая форма использования префикса подчёркивания для имен ваших методов.

Кроме того, мне пришло в голову, что по крайней мере один человек интерпретировал первую строку моего ответа: "Насколько это сложно, действительно?" как снисходительный. Надеюсь, что это было только одно впечатление - я определенно не намеревался никому снисходительно относиться, но пытался только сформулировать свой ответ вокруг утверждения OP о том, что директива @synthesize xxx=_xxx; усложняет ситуацию. Там много, чтобы усвоить, когда вы начинаете; надеюсь, новое поведение "синтезировать по умолчанию" уменьшит нагрузку для новичков.

Ответ 2

Вы правы, используя

@synthesize foobar=_foobar;

в большинстве случаев немного бессмыслен, но на абстрактном уровне он позволяет полностью вернуть значение какой-либо другой переменной. Как в...

@synthesize foobar=fluffybunny;

Позволяет получить или установить значение fluffybunny каждый раз, когда вы используете аксессор .foobar

Однако с точки зрения сложности @synthesize вы предпочитаете писать

-(void)setFoobar:(id)aobject {
    [self willSetValueForKey:"foobar"];
    id old = foobar;
    foobar = [aobject retain];
    [old release];
    [self didSetValueForKey:"foobar"];
}

-(id)foobar {
    [self willAccessValueForKey:"foobar"];
    id obj = [self primitiveValueForKey:@"foobar"];
    [self didAccessValueForKey:"foobar"];    
    return obj;
}

или

@synthesize foobar;

Это не очень хорошо написано, так как я забыл, как это делать хорошо, но директива @synthesize останавливает вас, чтобы писать аксессоры так много раз. Это одна из вещей, которые сильно всасывали Obj-C 1.0.

Бесплатный код, не сбивайте его.