Verwendung der Objekteigenschaft von NSNotificationcenter

72

Könnte mir bitte jemand zeigen, wie man die Objekteigenschaft in NSNotifcationCenter verwendet. Ich möchte damit einen ganzzahligen Wert an meine Auswahlmethode übergeben können.

So habe ich den Benachrichtigungslistener in meiner UI-Ansicht eingerichtet. Da ich möchte, dass ein ganzzahliger Wert übergeben wird, bin ich mir nicht sicher, durch was Null ersetzt werden soll.

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


- (void)receiveEvent:(NSNotification *)notification {
    // handle event
    NSLog(@"got event %@", notification);
}

Ich versende die Benachrichtigung von einer anderen Klasse wie dieser. Der Funktion wird eine Variable namens index übergeben. Es ist dieser Wert, den ich mit der Benachrichtigung irgendwie auslösen möchte.

-(void) disptachFunction:(int) index
{
    int pass= (int)index;

    [[NSNotificationCenter defaultCenter] postNotificationName:@"myevent" object:pass];
    //[[NSNotificationCenter defaultCenter] postNotificationName:<#(NSString *)aName#>   object:<#(id)anObject#>
}
Dubbeat
quelle

Antworten:

105

Der objectParameter repräsentiert den Absender der Benachrichtigung, was normalerweise der Fall ist self.

Wenn Sie zusätzliche Informationen weitergeben möchten, müssen Sie die NSNotificationCenterMethode verwenden postNotificationName:object:userInfo:, die ein beliebiges Wertewörterbuch verwendet (das Sie frei definieren können). Der Inhalt muss eine tatsächliche NSObjectInstanz sein, kein integraler Typ wie eine Ganzzahl. Daher müssen Sie die Ganzzahlwerte mit NSNumberObjekten umschließen.

NSDictionary* dict = [NSDictionary dictionaryWithObject:
                         [NSNumber numberWithInt:index]
                      forKey:@"index"];

[[NSNotificationCenter defaultCenter] postNotificationName:@"myevent"
                                      object:self
                                      userInfo:dict];
Gavinb
quelle
Ich habe mich für Ihre Option entschieden. Das einzige zusätzliche, was ich tun musste, war, einen Autorelease-Pool um das Wörterbuch zu wickeln.
Dubbeat
3
(Oh, und meine Lösung ist die gleiche wie die von Matthew, ich habe es gerade geschafft, etwas schneller auf
Senden
1
Wenn Sie "Autorelease-Pool um das Wörterbuch wickeln" sagen, meinen Sie damit, dass Sie einen Aufruf zum Autorelease des Diktats hinzugefügt oder ein tatsächliches NSAutoreleasePool-Objekt erstellt haben? Letzteres ist nur erforderlich, wenn Sie sich in einem sekundären Thread befinden, und Ersteres ist für Klasseninitialisierer dieser Form nicht erforderlich, da es nicht init oder neu ist.
Gavinb
Beachten Sie beim Festlegen des Objekts auch Folgendes: "Der Name und die Objektparameter beider Methoden werden verwendet, um zu entscheiden, ob die Kriterien einer veröffentlichten Benachrichtigung mit dem Beobachter übereinstimmen. Wenn der Name festgelegt ist, werden nur Benachrichtigungen mit diesem Namen ausgelöst. Wenn jedoch nil gesetzt ist, stimmen alle Namen überein. Dasselbe gilt für das Objekt. Wenn also sowohl Name als auch Objekt gesetzt sind, werden nur Benachrichtigungen mit diesem Namen und dem angegebenen Objekt ausgelöst. Wenn jedoch sowohl Name als auch Objekt nil sind , dann werden alle veröffentlichten Benachrichtigungen ausgelöst. " - nshipster.com/nsnotification-and-nsnotificationcenter
Sinisa Drpa
82

Die objectEigenschaft ist dafür nicht geeignet. Stattdessen möchten Sie den userinfoParameter verwenden:

+ (id)notificationWithName:(NSString *)aName 
                    object:(id)anObject 
                  userInfo:(NSDictionary *)userInfo

userInfo Wie Sie sehen, handelt es sich um ein NSDictionary, das speziell zum Senden von Informationen zusammen mit der Benachrichtigung verwendet wird.

Ihre dispatchFunctionMethode wäre stattdessen ungefähr so:

- (void) disptachFunction:(int) index {
    NSDictionary *userInfo = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:index] forKey:@"pass"];
   [[NSNotificationCenter defaultCenter] postNotificationName:@"myevent" object:nil userInfo:userInfo];
}

Ihre receiveEventMethode wäre ungefähr so:

- (void)receiveEvent:(NSNotification *)notification {
    int pass = [[[notification userInfo] valueForKey:@"pass"] intValue];
}
Matthew Frederick
quelle
"Die Objekteigenschaft ist dafür nicht geeignet." Warum ist es nicht angemessen? Wie auch immer, wenn ich versuche, die Objekteigenschaft zu verwenden, um (zum Beispiel) einen NSString * zu übergeben. Was wird passieren?
Selvin
1
@ Selvin Es dient zum Senden des Objekts, das die Benachrichtigung veröffentlicht (Sie würden es festlegen, selfwenn Sie es verwenden möchten ). Was passiert, wenn Sie dort etwas anderes platzieren? Ich habe keine Ahnung, aber wenn ich raten müsste, könnte es die Dinge unter dem Deckmantel durcheinander bringen, wie das Notification Center, das nachverfolgt, was veröffentlicht werden muss. Warum riskieren, wenn es ein System gibt, mit dem Objekte herumgereicht werden können?
Matthew Frederick
3
"Ein NSNotification-Objekt (als Benachrichtigung bezeichnet) enthält einen Namen, ein Objekt und ein optionales Wörterbuch. Der Name ist ein Tag, das die Benachrichtigung identifiziert. Das Objekt ist ein Objekt, das das Poster der Benachrichtigung an Beobachter senden möchte Benachrichtigung - normalerweise das Objekt, das die Benachrichtigung selbst gesendet hat. Das Wörterbuch enthält möglicherweise zusätzliche Informationen zum Ereignis. " Klingt für mich wie wäre es völlig in Ordnung , etwas anderes als zu setzen selfund nilin object:.
Max
1
@mdorseif "normalerweise das Objekt, das die Benachrichtigung selbst gepostet hat" ist der Grund, warum es nicht der beste Ort ist. Hier setzen Sie den Anrufer im Allgemeinen ein. Wird nichts kaputt machen, ist aber nicht Standard. Warum also, wenn es einen perfekten Ort gibt, um die Daten zu speichern? Warum lassen Sie Ihr zukünftiges Selbst oder eine andere arme Seele sich fragen, warum der Anrufer selfnicht in dem Objekt ist, zu dem er gehört, sondern in andere zufällige Daten.
Matthew Frederick