I\'m working in Objective-C on the iPhone and need to know whether a \'Class\' inherits from \'NSObject\'.
I tried checking if it responds to an NSObject selector:
Go direct to the Objective-C runtime:
#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
does what it says, and it's safe to compare metaclasses by pointer in the Objective-C runtime because there is only exactly one instance of the metaclass for each class. The isa pointer is the only thing that's definitely in struct objc_object.
EDIT: additionally, there are known bugs in the iPhone simulator that cause some exceptions not to be caught by try/catch blocks. I've reported them as a bug to Apple and been told that mine was a duplicate, so they are definitely aware. Did you try your code on a real device or just in the simulator?
EDIT2: from the wider context given elsewhere in this conversation, something like this might be smarter:
#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
}
The class 'Class' does not inherit from NSObject. That means methods defined by NSObject (such as isKindOfClass
or respondsToSelector
) cannot be used on it.
What are you trying to do with it in the first place?
respondsToSelector:
is itself an NSObject-defined selector, so you can't use it. I don't believe there's a way to do this without getting very deep into the internals of Objective-C.
May I ask why you have objects that aren't descendants of NSObject? Apple very strongly recommends you don't attempt to create them, and with good reason.
You can use the methods isKindOfClass:
and isMemberOfClass:
to determine whether a class is a subclass of another class or if it is a particular class.