2011-01-10 5 views
12

w Objective-C, gdy zadeklarujesz zmienną instancji można sprawdzić, czy jest on zgodny z protokołem na zlecenie w czasie kompilacji tak:Sprawdzanie, czy obiekt jest zgodny z dwóch oddzielnych protokołach w Objective-C

id <MyProtocol> variable; 

Czy jest możliwe sprawdzenie, czy obiekt przypisany do zmiennej jest zgodny z dwoma oddzielnymi protokołami w czasie kompilacji? Jak w:

id <MyProtocol, MyOtherProtocol> variable; 

wiem, że mogę zrobić wykonawczego sprawdzenie za pomocą conformsToProtocol: i respondsToSelector et al, (co zrobić, zanim rzeczywiście użyciu obiektu dla zwiększenia bezpieczeństwa), a mógłbym napisać własne metody setter, które wykonuje sprawdzanie , ale chciałbym wiedzieć podczas kompilacji.

+0

Does not 'zmienną id ;' praca? Przynajmniej kompiluje się bez problemów ... – Vladimir

+0

Nie jestem obecnie na komputerze, który mogę sprawdzić, ale chciałbym wiedzieć o dyskusji, którą prowadzę z kolegą. – Jasarien

Odpowiedz

12

I że najlepiej jest używać własnego kodu:

id <MyProtocol, MyOtherProtocol> variable; 

a przed wywołaniem metody, należy sprawdzić, czy zmienna jest odpowiedzią na to, co chcesz zadzwonić :

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

Od Objective-C jest dynamiczny język, tylko deklarując zmienną protokół nie może zapewnić, że jest on zgodny z protokołem. Generuje głównie ostrzeżenia podczas budowania.

+0

Dzięki, po prostu musiałem wiedzieć, że składnia była poprawna i działała. – Jasarien

3

Nie zawsze można sprawdzić zgodność protokołu w czasie kompilacji, ponieważ obiekt (niekwalifikowany) typu id jest zawsze prawidłowym obiektem z perspektywy kompilatora. Na przykład,

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; 

Mając na uwadze powyższe, <P1, P2> daje ostrzeżenia w przypadku, gdy obiekt nie spełnia obu protokołów jeśli które mogą być znane w czasie kompilacji:

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

Tak, ta składnia jest poprawna.

Poprawny sposób, aby sprawdzić, czy dany przedmiot jest zgodny z protokołem jest, aby to zrobić:

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

Zauważ, że to działa zarówno jako metody instancji i metody klasy.

Jeśli z jakiegoś dziwacznego powodu nie można używać conformsToProtocol: można spaść do poziomu wykonawczego:

#import <objc/runtime.h> 

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