3

我在 iPhone 上使用 Objective-C,需要知道“类”是否继承自“NSObject”。

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

bool success = [myClass respondsToSelector:@selector(class)];

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

我试图捕获该异常,但似乎无法使用@try-@catch 捕获它。

有任何想法吗?

4

4 回答 4

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]) ...

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
}
于 2010-11-22T23:57:10.333 回答
4

您可以使用这些方法isKindOfClass:isMemberOfClass:确定一个类是另一个类的子类还是特定类。

于 2010-11-22T23:31:21.093 回答
1

respondsToSelector:本身就是一个 NSObject 定义的选择器,所以你不能使用它。如果不深入了解 Objective-C 的内部结构,我不相信有办法做到这一点。

请问为什么你有不是 NSObject 后代的对象?Apple 强烈建议您不要尝试创建它们,并且有充分的理由。

于 2010-11-22T23:38:33.140 回答
-3

“Class”类不继承自 NSObject。这意味着 NSObject 定义的方法(例如isKindOfClassor respondsToSelector)不能在其上使用。

你首先想用它做什么?

于 2010-11-22T23:38:59.023 回答