2010-11-08 6 views
38

Ich versuche, ein NSDictionary Formular eine UIView zu einem UIViewController mit NSNotificationCenter übergeben. Das Wörterbuch funktioniert gut zum Zeitpunkt der Benachrichtigung, aber in der Empfangsmethode kann ich nicht auf eines der Objekte im Wörterbuch zugreifen.Wie ein NSDictionary mit postNotificationName übergeben: Objekt:

Hier ist, wie ich das Wörterbuch erschaffe und veröffentlichen die Mitteilung ...

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

Im UIViewController ich den Betrachter setze ...

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

Für Testzwecke hotSpotMore sieht aus wie dies ...

Der erste NSLog funktioniert einwandfrei und zeigt den Inhalt von th an das Wörterbuch. Das zweite Protokoll wirft die folgende Ausnahme ...

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

Ich verstehe nicht, warum ich keine Objekte in dem übergebenen Wörterbuch zugreifen kann.

Vielen Dank im Voraus für jede Hilfe.

John

Antwort

110

Die erste NSLog Werke Anzeigen feinen den Inhalt des Wörterbuchs. Das zweite Protokoll führt die folgende Ausnahme ...

Das Programm versucht, Sie zu betrügen, es sieht aus wie es Ihr Wörterbuch ist, weil Ihr Wörterbuch in der Benachrichtigung. Anhand der Ausnahme können Sie sehen, dass Ihr Objekt tatsächlich aus einer Klasse namens NSConcreteNotification stammt.
Dies liegt daran, dass das Argument einer Benachrichtigungsmethode immer ein NSNotification-Objekt ist. dies funktionieren wird:

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

nur als Hinweis: Das Objekt wird in der Regel das Objekt, das die Benachrichtigung sendet, sollten Sie Ihren NSDictionary als userinfo senden.
ich glaube, es würde den Code verbessern, wenn Sie es so tun würden:

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


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

Der Objektparameter zwischen den verschiedenen Objekten zu unterscheiden verwendet wird, die eine Benachrichtigung senden.
Angenommen, Sie haben zwei verschiedene HotSpot-Objekte, die beide die Benachrichtigung senden können. Wenn Sie object in addObserver:selector:name:object: festlegen, können Sie für jedes Objekt einen anderen Beobachter hinzufügen. Die Verwendung von nil als Objektparameter bedeutet, dass alle Benachrichtigungen empfangen werden sollten, unabhängig vom Objekt, von dem die Benachrichtigung gesendet wurde.

E.g:

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 
} 
+0

große Hilfe !! Danke, das hat funktioniert. Ich sehe, dass ich die Themen zur Benachrichtigungsprogrammierung nicht sorgfältig genug gelesen habe. – user278859

+8

+1 für das Programm wird empfindungsfähig und versucht, Sie zu betrügen :) –

+0

Alte Post, aber immer noch sehr wertvoll. Danke dafür! Nur eine kurze Anmerkung: userInfo: nimmt ein NSDictionary. Wenn Sie versuchen, ein anderes Objekt zu übergeben, müssen Sie es in ein Wörterbuch einfügen. – Alex

3

Verfahren Matthias spricht und das, was ich denke, Sie sollten

ist
postNotificationName:object:userInfo: 

Wo Objekt ist der Absender und userinfo ist Ihr Wörterbuch benutzen.

4

Dies ist der beste Weg, um Ihre Wörterbuchdaten mit NSNotification zu übergeben.

Nachmeldung:

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

Observer hinzufügen für die Benachrichtigung Griff.

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

Put Benachrichtigungs-Handler-Methode.

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

Ich hoffe, diese Lösung Sie

+4

Ich folgte diesem Code und es funktionierte nicht für mich, weil der Argumenttyp sollte NSNotification und nicht NSDictionary – ericraio

+0

Bitte überprüfen Sie Ihren Code. Wenn Sie Ihren Code teilen, kann ich Ihnen helfen. Der obige Code funktioniert in meinen wenigen Anwendungen. –

+0

Funktioniert auch nicht für mich, das SourceDictionary ist immer leer –