2013-06-05 4 views
6

Ich gehe gerade durch den Beispielcode AVFoundation.Framework ->AVSimpleEditoriOS & Ich fand folgende Zeile, die ich nicht verstehen konnte.statischer Void-Zeiger in AVFoundation.Framework in Beispielcode

static void *AVSEPlayerItemStatusContext = &AVSEPlayerItemStatusContext; 
static void *AVSEPlayerLayerReadyForDisplay = &AVSEPlayerLayerReadyForDisplay; 

static void *AVSEPlayerItemStatusContext = nil; 
static void *AVSEPlayerLayerReadyForDisplay = nil; 

Über zwei Leitungen folgende betrachten, kann ich herausfinden, dass das sind 2 static void/generic Zeiger mit einem ausgefallenen Namen.

Nun zurück zu den 2 Zeilen, ich einfügen es hier wieder,

static void *AVSEPlayerItemStatusContext = &AVSEPlayerItemStatusContext; 
static void *AVSEPlayerLayerReadyForDisplay = &AVSEPlayerLayerReadyForDisplay; 

Heisst oben, 2 static void/generic Zeiger Bezug von seinen eigenen Speichern & warum wäre es, in welchem ​​Sinne gebraucht?

Ich brauche nur kleine Anleitung, um solche Codierungsmuster zu lernen. Warten auf Wissen.

Antwort

6

A sich selbst verweisende Zeiger

static void *foo = &foo; 

ist nur ein Verfahren einen eindeutigen Zeiger bei der Kompilierung zu erstellen.

In diesem "AVSimpleEditoriOS" Beispielprojekt werden diese Zeiger später als context Parameter für

[self addObserver:self forKeyPath:@"player.currentItem.status" options:NSKeyValueObservingOptionNew context:AVSEPlayerItemStatusContext]; 

und

[self addObserver:self forKeyPath:@"playerLayer.readyForDisplay" options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew context:AVSEPlayerLayerReadyForDisplay]; 

Der tatsächliche Wert des Kontextparameters spielt keine Rolle überhaupt, ist es nur einige einzigartige Wert, der an

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if (context == AVSEPlayerItemStatusContext) { 
     // Notification for @"player.currentItem.status" 
     // ... 
    } else if (context == AVSEPlayerLayerReadyForDisplay) { 
     // Notification for @"playerLayer.readyForDisplay" 
     // ... 
    } else { 
     // Something else, pass to superclass: 
     [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
    } 
} 
übergeben wird

(Alternativ könnte man den keyPath Parameter in observeValueForKeyPath überprüfen.) Siehe @Bavarious Kommentar unten für warum eindeutige Kontextzeiger im Allgemeinen gegenüber Schlüsselpfadzeichenfolgen bevorzugt werden.

+0

Bedeutet es - wir übergeben es als Kontext (genau wie eine eindeutige ID eines Datensatzes in der Datenbank) & wenn wir eine Antwort vom inneren Rahmen erhalten, können wir die Antwort für den Kontext identifizieren? –

+1

@Spark: Ja, genau. Der Kontextparameter von 'addObserver' benötigt eine Zeigervariable, also ist dies nur eine bequeme Methode zum Erzeugen einer eindeutigen Zeigervariablen. - Ich habe die Antwort ein wenig erweitert, um die Idee klarer zu machen. –

+4

Nur eine Anmerkung: eindeutige Kontextzeiger werden im Allgemeinen gegenüber Schlüsselpfadzeichenfolgen bevorzugt, da es möglich ist, dass eine der Oberklassen auch denselben Schlüsselpfad beobachtet. –