Ответ 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 протоколы.