Перейти сразу к выполнению 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
делает то, что он говорит, и это безопасно для сравнения метаклассов указателя на время выполнения Objective-C, потому что есть только ровно один экземпляр метакласса для каждого класса. Указатель isa - это единственное, что определенно в struct objc_object.
EDIT: кроме того, в симуляторе iPhone есть известные ошибки, которые вызывают некоторые исключения, которые не могут быть пойманы блоками try/catch. Я сообщил о них как об ошибке для Apple, и мне сказали, что мой дубликат, поэтому они определенно знают. Вы пробовали свой код на реальном устройстве или просто в симуляторе?
EDIT2: от более широкого контекста данного в другом месте в этом разговоре, что-то подобное может быть умнее:
#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
}
Я думаю, лучше спросить, как вы пришли иметь дело с этими классами, которые не наследовать от NSObject. Там не должно быть никаких протоколов. – Chuck 2010-11-22 23:33:16
@Chuck и `NSProxy`. – 2010-11-23 00:52:20
Вы имеете в виду `@selector (class)`. Я не думаю, что в SDK есть что-то, что отвечает на `+ class:`. – 2010-11-23 03:00:25