2009-09-05 3 views
38

Я иду из модели событий C#, и мне интересно, есть ли стандартный способ уведомления нескольких делегатов о событии?Несколько делегатов в Objective C

У меня есть протокол ClassCDelegate, который я хочу реализовать как ClassA, так и ClassB. Есть ли способ, которым я могу назначить экземпляр ClassC как ClassA, так и ClassB в качестве делегатов без необходимости вручную создавать список переменных делегата в ClassC и проходить через них?

ответ

73

Делегаты какао используются для осуществления инверсии управления и уменьшения необходимости подкласса. Полностью возможно иметь несколько делегатов для одного объекта, но это делается, когда имеет смысл делегировать разные решения различным объектам. Отличным примером этого является WebView от WebKit, в котором есть пять делегатов, отвечающих за такие разнообразные области, как политика загрузки и навигации по ресурсам.

Система событий-делегатов C#, которая позволяет объекту регистрироваться другим объектом, который будет уведомляться при возникновении определенного события, ближе всего к нескольким API-интерфейсам уведомлений, доступным из Cocoa. Различные интерфейсы API вы можете запустить через это, от самого высокого уровня к низшему:

  • NSNotificationCenter
  • NSDistributedNotificationCenter
  • CFNotificationCenter
  • уведомления Дарвин.

Все похожие по духу, поэтому я рассмотрю только тот, который вы использовали бы в этом случае: NSNotificationCenter.

Наблюдатели, такие как ClassA и ClassB, регистрируют свою заинтересованность в уведомлениях с помощью NSNotificationCenter. Они могут указать интерес

  • уведомлений с определенным именем от конкретного объекта
  • уведомления с определенным именем из любого объекта
  • уведомления от конкретного объекта.

Когда соответствующее уведомление отправляется в центр уведомлений, наблюдатели уведомляются, вызывая метод, который они поставили во время регистрации в центре уведомлений. Метод всегда имеет один и тот же тип: он ничего не возвращает и принимает один аргумент, объект NSNotification.

Вы, как правило, обрабатывать ситуацию, имея ClassC объявить константу для имени уведомления в заголовочном файле, например,

extern NSString *const ClassCSomethingDidHappenNotification; 

Заинтересованные наблюдатели, такие как ClassA и ClassB, может затем зарегистрировать заинтересованность в этом уведомление:

[[NSNotificationCenter defaultCenter] 
    addObserver:self 
    selector:@selector(handleSomethingDidHappen:) 
     name:ClassCSomethingDidHappenNotification     
     object:aClassCObject]; 

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

Когда происходит событие, связанное с уведомлением, ClassC сообщение с уведомлением центра уведомлений:

[[NSNotificationCenter defaultCenter] 
    postNotificationName:ClassCSomethingDidHappenNotification 
       object:self]; 

Центр уведомлений будет просматривать список наблюдателей, найти те, которые соответствуют этому уведомлению, а также вызвать соответствующий метод.

+1

Отличное представление об уведомлениях и их сходствах и отличиях от делегатов. –

+1

Согласовано, это отличное значение для делегатов и уведомлений (слушателей). Это несколько нечеткая строка (например, мы часто уведомляем делегатов о завершении асинхронных задач), но она платит, чтобы понять различие. –

2

У вас может быть только один объект-делегат. Если вы хотите уведомить различные объекты об изменениях, вы должны использовать NSNotificationCenter и отправлять сообщения NSNotification, которые ваши объекты могут прослушивать.

+9

Собственно, это соглашение, но не строгое ограничение. Все склонны думать только о методе 'setDelegate:', но существует неограниченная гибкость. –

3

Вы также можете иметь один объект, обрабатывающий событие, а затем пересылать его второму объекту.

3

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

10

Альтернативой центра уведомлений является использование подкласса NSProxy для пересылки сообщений, детализированные в проводке по адресу:

http://engineering.hoteltonight.com/handling-multiple-delegates-in-ios

Класс HTDelegateProxy доступен по адресу:

https://github.com/hoteltonight/HTDelegateProxy

+0

Отличный ответ, спасибо! – jonsibley

1

Попробуйте MultiDelegate, он позволяет пересылать методы делегатов на любое количество объектов делегата.

Смежные вопросы