Istnieje metoda -[NSObject conformsToProtocol:]
w celu sprawdzenia, czy określony protokół został przyjęty, czy nie. Czy istnieje jakaś metoda uzyskania wszystkich przyjętych protokołów dla danej klasy, zamiast sprawdzania listy?Czy istnieje metoda introspekcji, aby uzyskać wszystkie przyjęte protokoły dla klasy w Objective-C?
Czy istnieje metoda introspekcji, aby uzyskać wszystkie przyjęte protokoły dla klasy w Objective-C?
Odpowiedz
Jest bardziej eleganckie rozwiązanie: class_copyProtocolList()
bezpośrednio zwraca przyjęte protokoły klasy. Użycie:
Class cls = [self class]; // or [NSArray class], etc.
unsigned count;
Protocol **pl = class_copyProtocolList(cls, &count);
for (unsigned i = 0; i < count; i++) {
NSLog(@"Class %@ implements protocol <%s>", cls, protocol_getName(pl[i]));
}
free(pl);
Należy pamiętać, że ta lista nie zawiera protokołów adoptowanych przez nadklasy, więc - w zależności od tego, do czego jest używana ta lista - konieczne może być przejście do łańcucha nadklasowego i ponowne wywołanie metody class_copyProtocolList(). –
@MartinR Dokładnie, naprawdę ciężko mi było dowiedzieć się dlaczego to nie wymienia protokołów dla 'NSMutableDictionary' ... –
jest to świetna odpowiedź. Wszystko działało dobrze. Może nie działać z ARC. ale na pewno będzie działać bez ARC. Dzięki. –
Można spróbować objc_copyProtocolList
Tj otrzymasz listę wszystkich protokołów, a następnie sprawdź, czy bieżący obiekt jest zgodny z określonym protokołem przez iterowanie listy.
Edit:
H2CO3 rozwiązanie jest naprawdę lepszy
Lub 'class_copyProtocolList()'. –
Jak praktycznie z niego korzystać? –
Masz na myśli, że powinienem napisać kod? – Max
Jest dokładnie NSObject +conformsToProtocol
; Zgodność protokołu jest zadeklarowana jako część @interface
, więc nie jest specyficzna dla każdej instancji. Np.
if([[self class] conformsToProtocol:@protocol(UIScrollViewDelegate)])
NSLog(@"I claim to conform to UIScrollViewDelegate");
Nie trzeba w ogóle rezygnować z metod uruchomieniowych poziomu C, przynajmniej dla pierwszej części pytania. Nie ma nic w NSObject
, aby uzyskać listę obsługiwanych protokołów.
Co dokładnie próbujesz osiągnąć z tym? –
@ RichardJ.RossIII Często używałem protokołu, gdzie potrzebuję jakiegoś ogólnego obiektu, aby móc wybrać, a następnie wysłać pracę do odpowiedniego celu (np. Uniwersalny 'UITableViewDataSource', aby móc wybrać odpowiednią komórkę dla danego obiekt, a następnie ustawić ten obiekt); Sądzę, że jest to łatwiejsze w utrzymaniu i wymaga mniej redeclaracji, aby dyspozytor mógł znaleźć odpowiednie cele za pośrednictwem środowiska wykonawczego, a następnie zapytać ich, czego się spodziewają. Jakieś myśli na ten temat? – Tommy