Alex Turner
Alex Turner

Reputation: 247

How is 'isSubclassOfClass' not a valid selector when it is defined in NSObject?

I am trying to do some debugging on a project I am working on, and would like to know the kind of ViewController a specific variable is being assigned. So I created an if statement like so:

    if ([controller isSubclassOfClass:[UINavigationController class]]) {
        NSLog(@"It's a navigation controller!");

    }

'controller' is created just above using

DetailViewController *controller = (DetailViewController *)[[segue destinationViewController]topViewController];

DetailViewController is a simple class inheriting from UIViewController. However I'm getting a compiler error saying No visibile @interface for 'DetailViewController' declares the selector 'isSubclassOfClass:'

How is that possible? When I tripleTap the reference for isSubclassOfClass it says it's a class method defined in NSObject. How is it possible that DetailViewController doesn't know that selector since all objects inherit from NSObject??

Upvotes: 0

Views: 889

Answers (3)

Duncan C
Duncan C

Reputation: 131426

Both other responders gave you a correct answer to your question, but I wanted to clarify something.

Methods who's declaration start with a + are CLASS methods. The class object implements those methods, not instances of that class. So this method:

+ (BOOL)isSubclassOfClass:(Class)aClass

Is a class method.

You'd use it like Jeffery Thomas demonstrated in the first part of his answer:

[[controller class] isSubclassOfClass:[UINavigationController class]]

The [controller class] bit fetches the class object for the controller object, and then sends that class object the isSubclassOfClass message.

In contrast, the method isKindOfClass:

- (BOOL)isKindOfClass:(Class)aClass

...is an instance method. You can tell because it's declaration starts with a "-" instead of a "+". Learn to look for the "+" or "-" at the beginning of every method declaration to see if it's a class method or an instance method. And if the compiler isn't letting you send a message that you see in the docs, go back and double-check. I've been programming in Objective-C for quite a few years now and this still bites me occasionally.

You send the isKindOfClass message to an instance of the object you want to test for class membership:

[controller isKindOfClass:[UINavigationController class]]

Upvotes: 4

Jeffery Thomas
Jeffery Thomas

Reputation: 42588

The standard way of doing this is -isKindOfClass:, not +isSubclassOfClass:, but it's possible to use +isSubclassOfClass:.

Using the instance method -isKindOfClass:

if ([controller isKindOfClass:[UINavigationController class]]) {
    NSLog(@"It's a navigation controller!");
}

Using the class method +isSubclassOfClass:

if ([[controller class] isSubclassOfClass:[UINavigationController class]]) {
    NSLog(@"It's a navigation controller!");
}

Upvotes: 4

jrturton
jrturton

Reputation: 119252

When I tripleTap the reference for isSubclassOfClass it says it's a class method defined in NSObject.

It's a class method, and you're using it on an instance. Try isKindOfClass.

Upvotes: 2

Related Questions