Цель Объявление делегата C

Может ли кто-нибудь сказать мне разницу между

@property (nonatomic, weak) id delegate;

@property (nonatomic, weak) id  <protocol_name> delegate;

@property (nonatomic, weak) UIViewController * <protocol_name> delegate;

Ответы

Ответ 1

@property (nonatomic, weak) id delegate;

Это указывает, что объекты текущего класса имеют делегат, который может быть любого типа. Спецификатор weak является общим для объектов делегата, так как это означает, что объект с делегатом не увеличивает счетчик ссылок делегата (в ARC-talk "держите ссылку на него" ). A weak ссылка для делегата - стандартная практика.

@property (nonatomic, weak) id < protocol_name > delegate;

Это указывает, что объекты текущего класса имеют делегат, который может быть любого типа (id), но должен соответствовать протоколу protocol_name. Это особенно полезно, поскольку класс, содержащий делегата, знает, что есть определенные сообщения, которые он может отправить своему делегату, и "знать", что делегат будет отвечать на них.

@property (nonatomic, weak) UIViewController * < protocol_name > delegate;

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


РЕДАКТИРОВАТЬ: Протоколы

Скажем, вы объявляете класс следующим образом:

@interface MyObject : NSObject <MyDelegateProtocol>
// ...
@end

<MyDelegateProtocol> в этом объявлении означает, что MyObject реализует методы, определенные в протоколе MyDelegateProtocol (т.е. "соответствует протоколу" ).

Определение протокола (до определения класса, очевидно) может выглядеть так:

@protocol MyDelegateProtocol <NSObject>
@required
- (void)method1;
- (void)method2;
@optional
- (void)method3;
@end

Это означает, что любой объект, "соответствующий" протоколу MyDelegateProtocol , должен реализовывать методы, называемые -(void)method1 и -(void)method2. И, необязательно, может включать реализацию для сообщения -(void)method3.

Это чрезвычайно полезная информация для объектов-делегатов (имя протокола может быть любым, кстати, я просто включаю слово "делегат", чтобы было очевидно, что он используется в качестве протокола делегата).

Если теперь определяет другой класс:

@property (nonatomic, weak) id<MyDelegateProtocol> delegate;

класс знает, что он может полагаться на реализации -method1 и -method2, которые будут реализованы его делегатом, и -method3 также может быть реализован (что он может проверить с помощью кода таких как:)

if ([self.delegate respondsToSelector:@selector(method3)]) {
    [self.delegate method3];
}
else {
    // Delegate doesn't implement -method3.
}

Проверка не нужна для -method1 и -method2, поскольку эти методы @required определяют определение протокола и могут вызывать их, когда захотят.

Класс может также использовать более одного протокола за раз (например, <Proto1, Proto2, UITableViewDelegate>) - для более полного обзора протоколов, Apple Docs on протоколы.

Ответ 2

@property (неатомный, слабый) id делегат;

Свойство без определенного типа или реализации протокола. При вызове методов на delegate все идет - компилятор будет доверять вам, если он увидит, что метод существует где-то, и время выполнения проверяет, лежали ли вы.

@property (неатомный, слабый) id < имя_файлa > делегат;

Свойство без определенного типа, но которое реализует указанный протокол. Вы можете вызывать только методы из этого протокола (если только вы не выполняете кастинг). Любой экземпляр, который установлен в свойство, должен соответствовать протоколу (или, опять же, вам нужно какое-то литье).

@property (неатомный, слабый) UIViewController * < имя_файлa > делегат;

Свойство с определенным типом (UIViewController) и которое реализует указанный протокол. Вы можете вызывать только методы из этого протокола и из класса UIViewController (если только вы не выполняете кастинг). Любой экземпляр, который установлен в свойство, должен соответствовать протоколу и быть подклассом UIViewController (или, опять же, вам нужно некоторое литье).

Ответ 3

В первом примере:

@property (nonatomic, weak) id delegate;

вы создаете свойство типа id, которое является "любым" типом в объекте c с именем - делегатом.

Второй пример:

@property (nonatomic, weak) id < protocol_name > delegate;

создается свойство идентификатора типа, которое должно соответствовать протоколу protocol_name с именем - delegate.

Последний пример:

@property (nonatomic, weak) UIViewController * < protocol_name > delegate;

вы создаете свойство типа UIViewController (указатель на UIViewController), который должен соответствовать протоколу protocol_name с именем-delegate.