@property и @synthesize в target-c - PullRequest
       4

@property и @synthesize в target-c

18 голосов
/ 28 апреля 2011

Пока я играл и выяснил, как все работает в 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 =.

Ответы [ 2 ]

30 голосов
/ 28 апреля 2011

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

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

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

id _delegate;

и

@synthesize delegate=_delegate;

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

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

17 голосов
/ 28 апреля 2011

Вы правы, использование

@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.

Бесплатный код, не стучите по нему.

...