Нет ничего плохого в том, что у вас есть делегат для синглтона, но он создает множество крайних случаев, которые вам нужно обработать.Например:
Если объект A вызывает setDelegate:, после чего сразу же объект B вызывает setDelegate: тогда объект A никогда не получит вызовов делегатов.
Вы должны проверить, являетесь ли вы делегатом, прежде чем отключать делегата синглтона.Обычно в dealloc
вы звоните singleton.delegate = nil;
.Если какой-то другой объект стал делегатом после того, как вы это сделали, то вы просто вызвали неожиданное прекращение его делегирования.
Синглеты с делегатами не являются общепринятым шаблоном.Ваши решения должны различаться в зависимости от того, насколько надежен ваш вариант использования.Вот некоторые решения (в порядке самых простых -> самых надежных).
Упрощайте
Создайте свое приложение так, чтобы в нем никогда не было нескольких объектов, являющихся делегатом-одиночкой нав то же время (это может быть невозможно).
NSNotification
Используйте NSNotificationCenter для сигнализации о событиях вместо делегирования.См. Некоторые другие ответы, опубликованные в этой теме.
Несколько делегатов
Расширьте свой синглтон для поддержки нескольких делегатов.Замените setDelegate:
на: addDelegate:
и removeDelegate:
@property (atomic) NSMutableArray *delegates;
- (void)addDelegate:(NSObject * <YourProtocol>)foo {
[self.delegates addObject:foo];
}
- (void)removeDelegate:(NSObject * <YourProtocol>)foo {
[self.delegates removeObject:foo];
}
- (void)signalDelegateEvent {
[self.delegates enumerateObjectsUsingBlock:^(id<YourProtocol> obj,
NSUInteger idx,
BOOL *stop) {
// call delegate method `foo` on each delegate
if ( [obj respondsToSelector:@selector(foo)]) {
[obj foo];
}
}];
}
Я успешно использовал шаблон с несколькими делегатами во многих приложениях.Будьте осторожны, подумайте о том, как многопоточность влияет на вещи, если вы выберете этот подход.