2011-01-10 5 views
12

In Objective-C, wenn Sie eine Instanz Variable deklarieren können Sie prüfen, ob es bei der Kompilierung auf ein Protokoll auf Zuweisung entspricht in etwa so:prüfen, ob ein Objekt entspricht zwei getrennte Protokolle in Objective-C

id <MyProtocol> variable; 

Ist es möglich zu überprüfen, ob ein Objekt, das der Variablen zugewiesen ist, zur Kompilierzeit zwei separaten Protokollen entspricht? Wie in:

id <MyProtocol, MyOtherProtocol> variable; 

ich weiß, ich Laufzeit tun kann mit conformsToProtocol: und respondsToSelector Kontrolle et al, (was ich, bevor sie tatsächlich das Objekt für zusätzliche Sicherheit verwendet wird), und ich konnte meine eigene Setter-Methode schreiben, dass der Scheck tut , aber ich möchte es zur Kompilierzeit wissen.

+0

nicht 'id Variable;' Arbeit? Zumindest kompiliert es ohne Probleme ... – Vladimir

+0

Ich bin derzeit nicht an einem Computer, den ich überprüfen kann, aber ich würde gerne für eine Diskussion, die ich mit einem Kollegen habe, wissen. – Jasarien

Antwort

12

I denke, das beste Ihren eigenen Code zu verwenden:

id <MyProtocol, MyOtherProtocol> variable; 

Und vor Aufruf einer Methode, ob die Variable reagiert auf das, was Sie anrufen möchten :

if ([variable respondsToSelector:@selector(aMethod:)]) { 
    [variable aMethod:nil]; 
} 

Da Objective-C eine dynamische Sprache ist, sondern nur das variable Protokoll erklärt versichern kann, nicht, dass es das Protokoll entspricht. Es generiert meist Warnungen beim Erstellen.

+0

Danke, ich musste nur wissen, dass die Syntax gültig war und funktionierte. – Jasarien

3

Sie können die Protokollkonformität nicht immer in der Kompilierzeit überprüfen, da ein Objekt vom (nicht qualifizierten) Typ id immer ein gültiges Objekt aus der Sicht des Compilers ist. Zum Beispiel

id<P1> p1; 
id<P2> p2; 
id p0; 

// compiler warning: assigning to 'id<P1>' from incompatible type 'id<P2>' 
p1 = p2; 

// no compiler warning 
p0 = p2; 
p1 = p0; 

aber sagen, dass <P1, P2> geben Ihnen Warnungen, falls das Objekt entspricht nicht beide Protokolle wenn, die zum Zeitpunkt der Kompilierung bekannt sein können:

id<P1> p1; 
id<P2> p2; 
id<P1, P2> p12; 
id<P1, P2> q12; 
id p0; 

p12 = p1; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P1>' 
p12 = p2; // warning: assigning to 'id<P1,P2>' from incompatible type 'id<P2>' 
p12 = q12; // no compiler warning 

// no compiler warning 
p0 = p1; 
p12 = p0; 
47

Ja, diese Syntax ist korrekt.

Der korrekte Weg, um zu überprüfen, ob ein Objekt zu einem Protokoll entspricht, dies zu tun:

if ([myObj conformsToProtocol:@protocol(MyProtocol)]) { 
    //conformance! 
} 

Beachten Sie, dass diese sowohl als Instanz Verfahren und eine Klassenmethode funktioniert.

Wenn aus unerfindlichen Gründen nicht die conformsToProtocol: verwenden können, können Sie auf das Runtime-Ebene Dropdown:

#import <objc/runtime.h> 

Protocol * p = objc_getProtocol("MyProtocol"); 
if (class_conformsToProtocol([myObj class], p)) { 
    //conformance! 
}