2013-10-28 3 views
0

Это нормально, что мой основной класс прослушивает множество уведомлений? например:Может ли один класс прослушать много уведомлений?

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(touched:) name:@"touch" object:nil]; 

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(done:) name:@"touch" object:nil]; 

[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(error:) name:@"touch" object:nil]; 

Мой главный класс слушает многие ее дочерние сообщения. делегаты - слишком большая работа, поэтому я попытался сбежать.

+3

Это может быть сделано, но вы действительно должны взвешивать недостатки и преимущества шаблона уведомлений и подходит ли ваш проект , Если у вас есть основной класс, МОЖЕТ быть в том, что классический шаблон делегирования будет лучше, по крайней мере, для некоторых из этих уведомлений ... –

+1

Если вы знаете, кто является получателем и какие сообщения он отвечает, вы должны использовать делегирование. Уведомления всегда доставляются в потоке, в котором было отправлено уведомление, которое не может быть тем же самым потоком, в котором наблюдатель зарегистрировал себя. –

ответ

1

Да, объект может слушать столько уведомлений, сколько вы хотите. NSNotificationCenter фактически является хэш-картой (на логическом уровне, а не в ее реализации). Он связывает имя уведомления с объектом, который будет обрабатывать его, и селектор (функция объекта для ответа на уведомление). Фактически, многие функции операционной системы основаны на NSNotificationCenter, например уведомления по умолчанию, опубликованные, когда приложение на iOS входит в фоновый режим или выходит на передний план. Вы можете зарегистрировать столько объектов, сколько хотите, в центре уведомлений, так как столько обратных вызовов, сколько вы хотите.

Однако, более подходящий вопрос: вы действительно хотите?

NSNotificationCenter может иметь многопоточность при использовании/злоупотреблении. Помните, что если вы основываете шаблон отправителя-слушателя исключительно на NSNotificationCenter, вы можете обнаружить ошибки в охоте, которые приводят к сложным обнаружению и воспроизведению сбоев. Конечно, есть функция addObserverForName: object: queue: usingBlock: ', которая позволяет вам контролировать поток, который вы хотите вызвать callback, но в этом случае, если вы не начнете передавать параметры объекта (те, которые используют self .myVar), используя кастинг «__weak __block», у вас могут быть утечки памяти. Не говоря уже о том, что по мере роста вашей программы вам придется обратить внимание на то, что поток отправляет уведомление, и где он будет обрабатываться, чтобы избежать многопоточных проблем. В этом случае, следуя всем лучшим практикам, использующим NSNotificationCenter, может возникнуть беспорядочный не очень эффективный код.

Говоря о нечитаемом коде, NSNotificationCenter может очень легко сделать ваше приложение незаменимым. Представьте, что произойдет, если вы используете только функции обратного вызова. У вас будет программа спагетти, полная обратных вызовов, где вы не сможете определить, куда они идут (вам нужно будет выполнить полный текстовый поиск для каждого).

Итак, если меня попросят дать простое соображение по дизайну, я бы сказал, что вы должны использовать NSNotificationCenter только тогда, когда у вас есть уведомление в вашем дизайне, на которое могут ответить ноль или более объектов, которые не нуждаются в любая логическая корреляция друг с другом или объект, инициирующий уведомление. В любом другом случае я рекомендую посмотреть шаблон делегата, который Objective C обрабатывает так красиво.

Я знаю, что это больше, чем вы просили, но я не мог просто ответить «да, поставил столько наблюдателей уведомлений, сколько пожелаете», не обсуждая последствий этого.

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

+0

ОК получил, спасибо большое. я вижу, что почему-то многие говорят о плохих вещах при уведомлении и удивляются, почему тогда Apple все-таки это сделала? я использую его, чтобы один класс (слой/представление) передавал сообщение в основное представление, - что кто-то коснулся его. – Curnelious

+0

NSNotificationCenter - очень важная и полезная функция. «Плохое имя» происходит от того факта, что многие разработчики не используют его правильно, и они склонны злоупотреблять им, создавая таким образом код спагетти. Подобно синглтонам, которые обычно полезны, но их легко злоупотреблять и создавать плохой код. – csotiriou

0

A. Есть ли копия & ошибка в пасте? Вы регистрируете три метода одного и того же наблюдателя в одном уведомлении. Вы можете просто зарегистрировать один метод, который «вызывает» другие. Поэтому нет причин делать то, что вы хотите сделать.

B. Разница между уведомлениями и делегатами не связана с потоком. Оба выполняются по внешнему потоку по умолчанию. (Вы можете изменить это очень легко, если хотите, но снова для обоих.)

C. Реальное различие заключается в том, что оповещения косвенны, когда направляются сообщения делегатов. Отправитель уведомления может столкнуться с неизвестным количеством неизвестных получателей. Делегирующий объект работает вместе с конкретным делегатом. Вы можете сравнить это с уведомлениями (неинтерактивными) вещания ТВ соответственно. делегируя интерактивное IP-телевидение. (Хорошо, это упрощено.) В результате делегат может изменить поведение делегирующего объекта, в то время как наблюдатель уведомления (какой?) Не может изменить поведение отправителя уведомления.

Если у вас есть определенное партнерство объектов в вашем дизайне, вам действительно нужно использовать делегирование. Более или менее работа, безусловно, не является поводом для изменения этой позиции. (И я не вижу, что это даже правда.)

0

Короткий ответ - да. Вы можете зарегистрировать столько уведомлений, сколько вам нужно.

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

(Вы можете наблюдать уведомления временно тоже, но звучит, как вы еще не там)

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