Вы никогда не вызываете метод делегатов print
.Делегат не может читать ваши мысли и автоматически называть вещи.Давайте рассмотрим небольшой пример того, как должны работать делегаты.
Предположим, у нас есть класс с именем Delay
, единственное, что он делает, - это подождет, когда будет вызван start
, и затем скажетэто делегат, что он ждал.При желании делегат может Delay
сообщить, сколько ждать, если клиенту все равно, предполагается задержка в 1 секунду.
Некоторые правила:
- Первый аргумент из всехМетоды делегата должны быть самим отправителем, никогда не иметь методов делегата без аргументов.
- Имя метода делегата должно включать одно из слов:
will
- если метод вызывается до того, как произойдет что-то неизбежное,Пример application
Will
Terminate:
did
- если метод вызывается после того, как что-то произошло.Пример scrollView
Did
Scroll:
should
- если метод возвращает BOOL для сигнала, если что-то должно произойти.Пример textField
Should
Clear:
- Назовите метод, чтобы сказать, что произошло, а не то, что вы ожидаете от делегата.
- Единственное исключение - если клиент должен что-то вернуть, тогда это что-то должно быть частью имени.Пример:
tableView:
editingStyle
ForRowAtIndexPath:
Вот простое определение и реализация.Обратите внимание, что я даже не проверяю, был ли установлен делегат, поскольку вызов методов на nil
в любом случае просто игнорируется.
// Delay.h
@protocol DelayDelegate;
@interface Delay : NSObject {
@private
id<DelayDelegate> _delegate;
}
@property(nonatomic, assign) id<DelayDelegate> delegate;
-(void)start;
@end
@protocol DelayDelegate <NSObject>
@required
-(void)delayDidComplete:(Delay*)delay;
@optional
-(NSTimeInterval)timeIntervalForDelay:(Delay*)delay;
@end
// Delay.m
@interface Delay
@synthesize = delegate = _delegate;
-(void)start {
NSTimeInterval delay = 1.0;
if ([self.delegate respondsToSelector:@selector(timeIntervalForDelay:)]) {
delay = [self.delegate timeIntervalForDelay:self];
}
[self performSelector:@selector(fireDelay) withObject:nil afterDelay:delay];
}
-(void)fireDelay {
[self.delegate delayDidComplete:self];
}
@end