Подтвердить что ты не робот

Как передать NSDictionary с postNotificationName: object:

Я пытаюсь передать форму NSDictionary UIView в UIViewController, используя NSNotificationCenter. Словарь отлично работает во время публикации уведомления, но в методе приема я не могу получить доступ к каким-либо объектам в словаре.

Вот как я создаю словарь и размещаю уведомление...

itemDetails = [[NSDictionary alloc] initWithObjectsAndKeys:@"Topic 1", @"HelpTopic", nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"HotSpotTouched" object:itemDetails];

В UIViewController я устанавливаю наблюдателя...

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

Для целей тестирования hotSpotMore выглядит так:

- (void)hotSpotMore:(NSDictionary *)itemDetails{
      NSLog(@"%@", itemDetails);
      NSLog(@"%@", [itemDetails objectForKey:@"HelpTopic"]);    
}

Первый NSLog отлично отображает содержимое словаря. Второй журнал выдает следующее исключение...

 [NSConcreteNotification objectForKey:]: unrecognized selector sent to instance 0x712b130

Я не понимаю, почему я не могу получить доступ к каким-либо объектам в переданном словаре.

Заранее благодарим за помощь.

Джон

4b9b3361

Ответ 1

Первый NSLog отлично работает содержимое словаря. второй журнал выбрасывает следующие исключение...

Программа пытается обмануть вас, это просто похоже, что это ваш словарь, потому что ваш словарь находится внутри уведомления. Из исключения вы можете видеть, что ваш объект на самом деле принадлежит классу с именем NSConcreteNotification.
Это связано с тем, что аргумент метода уведомления всегда является объектом NSNotification. это будет работать:

- (void)hotSpotMore:(NSNotification *)notification {
      NSLog(@"%@", notification.object);
      NSLog(@"%@", [notification.object objectForKey:@"HelpTopic"]);    
}

как подсказка: объект обычно является объектом, который отправляет уведомление, вы должны отправить NSDictionary как userInfo.
Я думаю, что это улучшит ваш код, если вы сделаете это следующим образом:

NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:@"HotSpotTouched" object:self userInfo:itemDetails];


- (void)hotSpotMore:(NSNotification *)notification {
      NSLog(@"%@", notification.userInfo);
      NSLog(@"%@", [notification.userInfo objectForKey:@"HelpTopic"]);    
}

Параметр объекта используется для различения различных объектов, которые могут отправлять уведомление.
Допустим, у вас есть два разных объекта HotSpot, которые могут отправлять уведомление. Когда вы устанавливаете object в addObserver:selector:name:object:, вы можете добавить другого наблюдателя для каждого из объектов. Использование nil в качестве параметра объекта означает, что все уведомления должны быть получены независимо от объекта, который отправил уведомление.

например:

FancyHotSpot *hotSpotA;
FancyHotSpot *hotSpotB;

// notifications from hotSpotA should call hotSpotATouched:
[[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(hotSpotATouched:) name:@"HotSpotTouched" 
       object:hotSpotA]; // only notifications from hotSpotA will be received

// notifications from hotSpotB should call hotSpotBTouched:
[[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(hotSpotBTouched:) name:@"HotSpotTouched" 
       object:hotSpotB]; // only notifications from hotSpotB will be received

// notifications from all objects should call anyHotSpotTouched:
[[NSNotificationCenter defaultCenter] addObserver:self 
       selector:@selector(anyHotSpotTouched:) name:@"HotSpotTouched" 
       object:nil]; // nil == "any object", so all notifications with the name "HotSpotTouched" will be received


- (void)hotSpotATouched:(NSNotification *)n {
    // only gets notification of hot spot A
}

- (void)hotSpotBTouched:(NSNotification *)n {
    // only gets notification of hot spot B
}

- (void)anyHotSpotTouched:(NSNotification *)n {
    // catches all notifications
}

Ответ 2

Это лучший способ передать данные словаря с помощью NSNotification.

Сообщение:

 [[NSNotificationCenter defaultCenter] postNotificationName:@"Put Your Notification Name" object:self userInfo:"Pass your dictionary name"];

Добавить наблюдателя для обработки уведомления.

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mydictionaryData:)  name:@"Put Your Notification Name" object:nil];

Поместите метод обработчика уведомлений.

- (void)mydictionaryData:(NSDictionary *)sourceDictionary{
      NSLog(@"%@", sourceDictionary);
    }

Надеюсь, это решение поможет вам.

Ответ 3

Метод, о котором говорит Маттиас, и тот, который, я думаю, вы должны использовать,

postNotificationName:object:userInfo:

Если объектом является отправитель, а userInfo - ваш словарь.