2010-11-08 11 views
38

Sto provando a passare un modulo NSDictionary un UIView a un UIViewController utilizzando NSNotificationCenter. Il dizionario funziona correttamente al momento della pubblicazione della notifica, ma nel metodo di ricezione non riesco ad accedere a nessuno degli oggetti nel dizionario.Come passare un NSDictionary con postNotificationName: oggetto:

Ecco come sto creando il dizionario e la pubblicazione della notifica ...

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

Nel UIViewController io pongo l'osservatore ...

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

A scopo di verifica hotSpotMore assomiglia questo ...

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

Il primo NSLog funziona bene visualizzando i contenuti di e dizionario Il secondo registro getta la seguente eccezione ...

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

Non capisco perché non posso accedere a qualsiasi oggetto nel dizionario passato.

Grazie in anticipo per qualsiasi aiuto.

John

risposta

110

Il primo NSLog funziona bene visualizzazione il contenuto del dizionario. Il secondo registro genera l'eccezione seguente ...

Il programma tenta di ingannare l'utente, sembra proprio come è il dizionario perché il dizionario è all'interno della notifica. Dall'eccezione puoi vedere che il tuo oggetto proviene effettivamente da una classe chiamata NSConcreteNotification.
Questo perché l'argomento di un metodo di notifica è sempre un oggetto NSNotification. questo funziona:

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

solo come un suggerimento: l'oggetto è di solito l'oggetto invia la notifica, è necessario inviare il vostro NSDictionary come userInfo.
penso che potrebbe migliorare il vostro codice se si desidera fare in questo modo:

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


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

Il parametro oggetto viene utilizzato per distinguere tra i diversi oggetti che possono inviare una notifica.
Supponiamo che tu abbia due oggetti HotSpot diversi che possono entrambi inviare la notifica. Quando si imposta object in addObserver:selector:name:object:, è possibile aggiungere un osservatore diverso per ciascuno degli oggetti. L'utilizzo di nil come parametro dell'oggetto significa che devono essere ricevute tutte le notifiche, indipendentemente dall'oggetto che ha inviato la notifica.

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

Great !! Grazie, ha funzionato Vedo che non ho letto gli argomenti di notifica di programmazione con sufficiente attenzione. – user278859

+8

+1 per il programma di diventare senziente e cercando di ingannare voi :) –

+0

Vecchio post, ma ancora molto prezioso. Grazie per questo! Solo una breve nota: userInfo: ci vorrà un NSDictionary. Se si sta cercando di passare un oggetto diverso si dovrà inserire in un dizionario. – Alex

3

Il metodo Matthias sta parlando e quello penso che si dovrebbe usare è

postNotificationName:object:userInfo: 

Dove oggetto è il mittente e userInfo è il dizionario.

4

questo è il modo migliore per passare i dati del dizionario con NSNotification.

messaggio di notifica:

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

Aggiungi Observer per gestire la notifica.

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

Put Metodo di gestione delle notifiche.

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

spero, questa soluzione vi aiuterà a

+4

Ho seguito questo codice e non ha funzionato per me perché il tipo di argomento deve essere NSNotification e non NSDictionary – ericraio

+0

Controllare il codice. Se condividi il tuo codice, allora posso aiutarti. Il codice sopra funziona nelle mie poche applicazioni. –

+0

Non funziona anche per me, il sourceDictionary è sempre vuoto –

Problemi correlati