Для того чтобы зарегистрироваться на получение уведомления, следует послать в центр уведомлений одно из двух сообщений.

В частности, метод addObserver: selector: паше: object: имеет следующие параметры:

observer:

Это экземпляр, которому посылается уведомление. Как правило, это экземпляр, доступный по ссылке self. Один экземпляр обычно не регистрирует другой экземпляр в качестве получателя уведомления.

selector:

Это сообщение, посылаемое экземпляру наблюдателя, когда имеет место уведомление. Специально назначенный для этой цели метод должен возвращать тип void (фактически нечего не возвращать) и принимать один параметр, которым должен быть объект типа NSNotif ication. Следовательно, этот параметр должен быть обозначен как NSNotif ication* или id. Не забудьте реализовать данный метод! Если центр сообщений посылает уведомление, отправляя сообщение, указанное в качестве параметра selector:, а метод, принимающий это сообщение, не реализован, то приложение завершится аварийно (см. главу 3).

name:

Это имя уведомления, которое требуется получить и которое представлено объектом типа NSString. Если же этот параметр указан как nil, значит, запрашиваются все уведомления, связанные с объектом, обозначаемым параметром ob j ect:. Как правило, имя встроенного в среду Cocoa уведомления является константой. Как пояснялось в главе 1, это удобно, поскольку компилятор выдаст предупреждение, если допустить ошибку в имени константы. Если ввести неверное имя уведомления непосредственно в виде литерала типа NSString, то компилятор не выдаст предупреждение, но никаких уведомлений непостижимым образом не будет получено, поскольку ни одно из них не носит введенное имя. Такую ошибку очень трудно обнаружить.

object:

Это объект интересующего уведомления, который, как правило, рассылает его. Если этот параметр указан как nil, значит, запрашиваются все уведомления с именем, обозначаемым параметром name:. (Если же оба параметра name: и object: указаны как nil, значит, запрашиваются все уведомления!)

Например, в одном из моих приложений требуется изменять интерфейс всякий раз, когда проигрыватель музыкальных записей на мобильном устройстве начинает воспроизводить другую песню. Прикладной интерфейс API для встроенного в мобильное устройство проигрывателя относится к классу MPMusicPlayerController, который посылает уведомление, когда в этом проигрывателе происходит смена воспроизводимой музыки. В документации на класс MPMusicPlayerController это уведомление обозначено как MPMusicPlaye rControllerNowPlayingltemDidChangeNotif ication в разделе уведомлений.

Как следует из документации, это уведомление вообще не рассылается, если не вызвать сначала метод экземпляра beginGeneratingPlaybackNotifications из класса MPMusicPlayerController. Такая архитектура весьма характерна для среды Cocoa, где экономится время и усилия на том, чтобы не отправлять некоторые сообщения до тех пор, пока они не будут фактически активизированы. Поэтому я первым делом получаю экземпляр класса MPMusicPlayerController и вызываю его метод следующим образом:

MPMusicPlayerController* mp = [MPMusicPlayerController iPodMusicPlayer];

[mp beginGeneratingPlaybackNotifications];

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

[[NSNotificationCenter defaultCenter] addObserver:self selector:0selector(nowPlayingltemChanged:)

name:MPMusicPlayerControllerNowPlayingltemDidChangeNotification object:nil];

Теперь всякий раз, когда рассылается уведомление MPMusicPlayerControllerNow PlayingltemDidChangeNotif ication, в моем приложении будет вызываться приведенный ниже метод nowPlayingltemChanged:.

- (void) nowPlayingltemChanged: (NSNotification*) n (

MPMusicPlayerController* mp = [MPMusicPlayerController iPodMusicPlayer]; self->_nowPlayingItem - mp.nowPlayingltem;

// ... и так далее ...

Зарегистрироваться для получения уведомлений можно также, вызвав метод addObserver ForName:object:queue:usingBlock::. Этот метод возвращает значение, конкретное назначение которого поясняется ниже. Параметр queue: этого метода обычно имеет пустое значение nil, а непустое его значение предназначено для многопоточной обработки в фоновом режиме. Параметры name: и object: подобны описанным выше параметрам метода а ddObserver: selector: name: obj ect:. Вместо наблюдателя и селектора в данном случае предоставляется блок, состоящий из конкретного кода, выполняемого при поступлении уведомления. Этот блок должен принимать в качестве единственного параметра сам объект уведомления типа NSNotification.

Такой способ регистрации для получения уведомлений имеет ряд существенных преимуществ. С одной стороны, для правильного функционирования метода addObserver: selector: name: obj ect: необходимо получить нужный селектор и реализовать соответствующий метод. С другой стороны, все нужные операции происходят в блоке и не требуют селектора и отдельного метода, как показано ниже.

MPMusicPlayerController* mp = [MPMusicPlayerController iPodMusicPlayer];

[mp beginGeneratingPlaybackNotifications];

id ob ” [[NSNotificationCenter defaultCenter] addObserverForName:MPMusicPlayerControllerNowPlayingItemDidChangeNotification object:nil queue:nil usingBlock:Л(NSNotification *n) ( self->_nowPlayingItem = mp.nowPlayingltem;

// ... и так далее ...

)

lb-

Рассмотрим, насколько понятным и удобным для сопровождения является такой код. Интенсивное применение метода addObserver: selector: name: object: означает, что прикладной код в конечном итоге будет усеян методами, которые существуют только для вызова из центра уведомлений. Однако об их назначении ничто не говорит, а следовательно, требует ввода в исходный код соответствующих комментариев, напоминающих об этом. Кроме того, эти методы отделены от вызова на регистрацию, и все это вместе делает прикладной код испещренным малопонятными методами и слишком запутанным. Теперь обратите внимание на то, что в блоке не нужно переопределять переменную экземпляра шр, как пришлось сделать в отдельном методе nowPlayingltemChanged:. Она по-прежнему находится в той области действия, где была определена несколькими строками кода раньше. В этом отношении блоки очень удобны!


 

 

 

Добавить комментарий