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
各クラスのメタクラスのインスタンスは 1 つしかないため、Objective-C ランタイムでポインターによってメタクラスを比較しても安全です。isa ポインターは、構造体 objc_object に確実にある唯一のものです。
編集: さらに、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
}