如何判断一个类是否继承自NSObject(Objective-C)

ben*_*ree 3 iphone reflection objective-c nsobject

我在iPhone上的Objective-C工作,需要知道'Class'是否继承自'NSObject'.

我试过检查它是否响应NSObject选择器:

bool success = [myClass respondsToSelector:@selector(class)];
Run Code Online (Sandbox Code Playgroud)

但你可以猜到发生了什么......它甚至没有响应"respondsToSelector:"所以它抛出了"不实现doesNotRecognizeSelector:"异常.

我试图捕获该异常,但看起来它不能被@ try- @ catch捕获.

有任何想法吗?

Tom*_*mmy 7

直接转到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]) ...
Run Code Online (Sandbox Code Playgroud)

class_getSuperclass做它说的,并且在Objective-C运行时通过指针比较元类是安全的,因为每个类只有一个元类的实例.isa指针是struct 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
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您更喜欢类似 Obj-C 的语法:https://gist.github.com/BillinghamJ/6709374 (2认同)
  • 您可能希望使用`object_getClass(classA)`而不是` - > isa` (2认同)