web-dev-qa-db-fra.com

Comment passer un NSDictionary avec postNotificationName: object:

J'essaie de passer un formulaire NSDictionary UIView à un UIViewController à l'aide de NSNotificationCenter. Le dictionnaire fonctionne correctement au moment où la notification est publiée, mais dans la méthode de réception, je ne peux accéder à aucun des objets du dictionnaire.

Voici comment je crée le dictionnaire et publie la notification ...

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

Dans l'UIViewController, je place l'observateur ...

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

À des fins de test, hotSpotMore ressemble à ceci ...

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

Le premier NSLog fonctionne très bien en affichant le contenu du dictionnaire. Le deuxième journal lève l'exception suivante ...

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

Je ne comprends pas pourquoi je ne peux accéder à aucun objet dans le dictionnaire passé.

Merci d'avance pour votre aide.

John

38
user278859

Le premier NSLog fonctionne très bien en affichant le contenu du dictionnaire. Le deuxième journal lève l'exception suivante ...

Le programme essaie de vous tromper, il semble que c'est votre dictionnaire car votre dictionnaire est dans la notification. De l'exception, vous pouvez voir que votre objet provient en fait d'une classe nommée NSConcreteNotification.
En effet, l'argument d'une méthode de notification est toujours un objet NSNotification. cela fonctionnera:

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

juste comme un indice: l'objet est généralement l'objet qui envoie la notification, vous devez envoyer votre NSDictionary en tant qu'utilisateurInfo.
Je pense que cela améliorerait votre code si vous le faisiez comme ceci:

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


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

Le paramètre objet est utilisé pour distinguer les différents objets qui peuvent envoyer une notification.
Supposons que vous disposez de deux objets HotSpot différents qui peuvent tous deux envoyer la notification. Lorsque vous définissez object dans addObserver:selector:name:object: vous pouvez ajouter un observateur différent pour chacun des objets. L'utilisation de nil comme paramètre d'objet signifie que toutes les notifications doivent être reçues, quel que soit l'objet qui a envoyé la notification.

Par exemple:

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
}
110
Matthias Bauch

C'est le meilleur moyen de transmettre vos données de dictionnaire avec NSNotification.

Notification après:

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

Ajouter un observateur pour gérer la notification.

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

Mettez la méthode du gestionnaire de notifications.

- (void)mydictionaryData::(NSNotification*)notification{
   NSDictionary* userInfo = notification.userInfo;
   NSLog (@"Successfully received test notification! %@", userInfo);}

J'espère que cette solution vous aidera

4
Amit Singh

La méthode dont parle Matthias et celle que je pense que vous devriez utiliser est

postNotificationName:object:userInfo:

Où objet est l'expéditeur et userInfo est votre dictionnaire.

3
Brabbeldas