Aller directement à l'exécution Objective-C:
#import <objc/runtime.h>
/* originally posted version — works because eventually class_getSuperclass(class)
returns nil, and class_getSuperclass(nil) does so also. */
BOOL classDescendsFromClass(Class classA, Class classB)
{
while(1)
{
if(classA == classB) return YES;
id superClass = class_getSuperclass(classA);
if(classA == superClass) return (superClass == classB);
classA = superClass;
}
}
/* shorter version; exits straight after classA turns into nil */
BOOL classDescendsFromClassShorter(Class classA, Class classB)
{
while(classA)
{
if(classA == classB) return YES;
classA = class_getSuperclass(classA);
}
return NO;
}
...
if(classDescendsFromClass(classToTest->isa, [NSObject class]) ...
class_getSuperclass
fait ce qu'il dit, et il est sûr de comparer métaclasses par pointeur dans l'exécution Objective-C, car il est seulement exactement une instance de la métaclasse pour chaque classe. Le pointeur isa est la seule chose qui soit définitivement dans la structure objc_object.
EDIT: En outre, il y a des bugs connus dans le simulateur iPhone qui causent quelques exceptions de ne pas être pris par des blocs try/catch. Je les ai signalés comme un bug à Apple et on m'a dit que le mien était un doublon, donc ils sont certainement au courant. Avez-vous essayé votre code sur un vrai appareil ou juste dans le simulateur?
EDIT2: du contexte plus large donné ailleurs dans cette conversation, quelque chose comme cela pourrait être plus intelligent:
#import <objc/runtime.h>
BOOL classRespondsToSelector(Class classA, SEL selector)
{
return class_getInstanceMethod(classA, selector) ? YES : NO;
}
....
if(classRespondsToSelector(instance->isa, @selector(respondsToSelector:))
{
// great, we've got something that responds to respondsToSelector:; do the
// rest of our querying through there
}
Je pense que la meilleure question est de savoir comment vous êtes à traiter avec ces classes qui ne sont pas hérite de NSObject. Il ne devrait pas y en avoir sauf Protocole. – Chuck
@Chuck et 'NSProxy'. –
Vous voulez dire '@selector (class)'. Je ne pense pas qu'il y ait quoi que ce soit dans le SDK qui réponde '' + class: '. –