Objective-C Runtime: najlepszy sposób na sprawdzenie, czy klasa jest zgodna z protokołem?

171

Mam klasę (ale nie mam instancji) i muszę wiedzieć, czy jest ona zgodna z określonym protokołem. Jednak klasa może być podklasą kilka razy, a class_conformsToProtocol () ignoruje protokoły zadeklarowane w nadklasach.

Mógłbym po prostu użyć class_getSuperclass () i rekurencyjnie sprawdzić wszystkie klasy w hierarchii w górę, aż nadklasa będzie zerowa. Zastanawiam się jednak, czy może to być nieefektywne w przypadku głęboko zagnieżdżonych hierarchii klas, a może jest na to lepszy sposób?

Innymi słowy, w jaki sposób metoda NSObject jest zgodna z protokołem zgodnym z protokołem, najlepiej zaimplementowana przy użyciu metod środowiska wykonawczego Objective-C, tak aby znajdowała protokoły w nadklasach?

 [myObject conformsToProtocol:@protocol(MyProtocol)];

Jeśli jestem na dobrej drodze z rekurencyjnym przechodzeniem w górę hierarchii klas, po prostu daj mi znać.

LearnCocos2D
źródło

Odpowiedzi:

309

Według dokumentów ,

[MyClass conformsToProtocol:@protocol(MyProtocol)];

powinno działać.

Wevah
źródło
4
Masz rację. Było późno i Xcode nie przedstawił żadnych sugestii dotyczących uzupełniania kodu. Sprawdziłem definicję Class i widząc, że jest to „typedef struct objc_class * Class”, nie sprawdziłem odwołania do klasy NSObject.
LearnCocos2D
Czy istnieje sposób, aby to zrobić na instancji zamiast na klasie? Mój self.delegateimplementuje wiele protokołów i chcę sprawdzić, czy jest zgodny z innymi niż jego klasa.
Konrad Piascik
@KonradPiascik Wystarczy nazwać na przykład zamiast: [someObject conformsToProtocol:@protocol(MyProtocol)].
Wevah
3

Lub, jeśli jest to ogólny wskaźnik, taki jak:

Class<MyProtocol> someClassPointer = nil;

możesz użyć:

[someClassPointer.class conformsToProtocol:@protocol(MyProtocol)];
Nikita
źródło