2 коротких сообщения о NSNotification Center

Во всех учебниках или примерах, которые я нахожу, они показывают двоеточие после имени селектора (getCurrentData:), например:

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

Поскольку в примерах после этого двоеточия ничего нет, я предполагаю, что указанный метод не принимает никаких аргументов. И у меня тоже нет, но когда я использую приведенный выше синтаксис, мое приложение вылетает и говорит unrecognized selector sent to instance Я удаляю двоеточие, и оно работает. Так почему же все примеры показывают двоеточие?

Во-вторых, если я действительно использовал селектор, требующий аргумента, как я могу это сделать? Если я сделаю это:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(createButtons:@"ten grand";) name:@"mapsReceived" object:nil ];

Он даже не скомпилируется; Я получаю массу ошибок, пока не удалю текстовую строку и двоеточие. Тем не менее, я могу вызвать этот метод со строкой, просто отлично, если использую его вне NSNotification. Есть ли способ сделать то, что я хочу здесь?


person johnbakers    schedule 23.08.2011    source источник


Ответы (5)


Во-первых, в большинстве примеров предполагается, что вы передаете уведомление методу. Например:

- (void)respondToNotification:(NSNotification *);

Это будет представлено как:

@selector(respondToNotification:)

Если вы удалите этот аргумент, это будет

@selector(respondToNotification)

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

person dtuckernet    schedule 23.08.2011

Когда NSNotificationCenter отправляет уведомление (через указанный вами селектор, например getCurrentData:), он передает экземпляр NSNotification, поэтому ваш метод должен принимать один аргумент, который является таким экземпляром.

См. http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html

person marramgrass    schedule 23.08.2011
comment
Вы не должны, вы должны. Должен подразумевает, что он не компилируется, что он и делает. Должен подразумевается, что если вы делаете по-другому, вы делаете это неправильно... и это правда. +1 тебе все же :D - person Kheldar; 23.08.2011
comment
Он может быть скомпилирован, но из документов, указанных выше: Селектор, указывающий сообщение, которое получатель отправляет уведомлениемObserver, чтобы уведомить его о публикации уведомления. Метод, указанный в notificationSelector, должен иметь один и только один аргумент (экземпляр NSNotification). +1 оценил, однако :) - person marramgrass; 23.08.2011

Ответ на первый вопрос заключается в том, что в Objective C двоеточие является частью имени функции. Если вы его опускаете, вы ссылаетесь на другую функцию, которая не принимает никаких параметров. Однако методы уведомлений всегда вызываются (и поэтому должны принимать) с одним параметром: объектом уведомления:

Вот выдержка из NSNotificationCenter Ссылка на класс:

«Метод, указанный в notificationSelector, должен иметь один и только один аргумент (экземпляр NSNotification)»

person Holger    schedule 23.08.2011

Если в конце есть двоеточие, то он принимает параметр. Вы ничего не передаете в вызове @selector. Ваш первый пример правильный, и ваш метод getCurrentData: должен выглядеть так.

-(void)getCurrentData:(NSNotification*)note
{
     //Implementation
}

Для каждого двоеточия, которое вы видите в селекторе, он принимает такие параметры, например, как @selector(aMethod:secondArg:thirdArg:), так и @selector(aMethod:::) имеют разные подписи, но оба будут принимать 3 аргумента.

person Joe    schedule 23.08.2011

Вы пытаетесь добавить наблюдателя и отправить сообщение в том же коде, это не работает. Вы объявляете, что ЭТОТ метод используется для реагирования на событие, как в [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(myMethod:) name:@"behaviorName" object:nil];

Затем он будет вызываться, когда произойдет событие, и вы можете передать ему специальный объект через параметр объекта для работы. Однако за двоеточием должен быть передан специальный объект инкапсуляции события (очевидно, NSNotification), см. документацию, для которой вы должны разработать свой метод myMethod:. Если вы пропустили объект в коде своего метода, то имеет смысл попытаться вызвать его, так как вы вызываете другой метод, по сути, перегрузку: p

person Kheldar    schedule 23.08.2011