target-c - Как правильно объявить делегатов?

Я новичок в разработке Objective-C и iOS, и в своем классе я объявляю протокол делегата.

Я нашел несколько примеров того, как это сделать, и все они очень похожи, но имеют некоторые различия, которые я хочу прояснить для себя и понять.

Пример 1:

(ссылки - https://stackoverflow.com/a/12660523/2117550 и https://github.com/alexfish/delegate-example/blob/master/DelegateExample/CustomClass.h )

МойКласс.h

#import <BlaClass/BlaClass.h>

@class MyClass; // removed in example 2
@protocol MyClassDelegate <NSObject>
@optional
- (void) myClassDelegateMethod:(BOOL)value;
@end

@interface MyClass : NSObject
@property (nonatomic, weak) id <MyClassDelegate> delegate;
@end

МойКласс.m

#import "MyClass.h"

@implementation MyClass 
@synthesize delegate; // removed in example 2

- (void) myMethodToDoStuff {
  [self.delegate myClassDelegateMethod:YES]; 
}

@end

Пример 2: (ссылки - http://www.tutorialspoint.com/ios/ios_delegates.htm)

На самом деле то же самое, за исключением этих двух отличий.

Чем они отличаются:

  • В примере 1 мы объявляем @class перед протоколом, действительно ли это необходимо? или просто лучшая практика. Второй пример отлично работает без этого объявления.
  • В примере 1 мы используем @synthesize delegate, поскольку я понимаю, что он создает геттеры/сеттеры для свойства, но нам это действительно нужно? Второй пример работает без этого.

Оба примера работают нормально, я просто хочу избавиться от путаницы, возникающей во мне.

Спасибо!


person Kosmetika    schedule 18.05.2014    source источник
comment
Рекомендуется передать исходный экземпляр делегату. Взгляните на реализацию делегата Apple (например, UITableViewDelegate) для лучших примеров правильно сформированных протоколов.   -  person Wain    schedule 18.05.2014
comment
Не забудьте проверить, отвечает ли делегат на селектор перед вызовом myClassDelegateMethod: поскольку myClassDelegateMethod: указан как @Optional.   -  person Jonathan    schedule 18.05.2014


Ответы (2)


Использование @class MyClass требуется, если методы протокола имеют ссылку на класс. Методы протокола обычно предоставляют параметр классу. Вы не делаете этого в своем примере, поэтому в этом нет необходимости.

Использование @synthesize некоторое время не требовалось. Не используйте его, если у вас нет особой причины для его использования.

person rmaddy    schedule 18.05.2014

@class сообщает компилятору, что класс существует до достижения его @interface. Это полезно, когда два заголовка класса/протокола должны #import только друг друга. Скорее всего, это произойдет после того, как вы создадите свой протокол.

@synthesize раньше были необходимы для создания геттеров и сеттеров, но теперь у нас также есть так называемые автоматические свойства. Если вы не используете @synthesize, компилятор создаст переменную экземпляра для хранения значения свойства и все равно сгенерирует геттеры и сеттеры. @synthesize дает вам немного больше контроля над процессом, но больше не нужен.

person zneak    schedule 18.05.2014