2

In a previous question, I mentioned that a Core Data class is receiving a message it doesn't understand (I believe it has something to do with NSFetchedResultsController), called

-(int) sectionOffset

In trying to find the cause of the bug, I tried to find out which class was the intended receiver, to no avail: there's no mention to this message in the docs or even in google.

As a last resort, I was planning to iterate over all NSObject's subclasses and ask (via instanceRespondsToSelector:) if it understands the message. Hopefully, that should give me a clue of what happening here.

So, is there a way to iterate through all the subclasses of a certain class? Is there a better way to do this?

Community
  • 1
  • 1
cfischer
  • 24,452
  • 37
  • 131
  • 214
  • 2
    There's a good chance that the message is being sent to some object that has been deleted and had it's address re-used to store a KCGIngredient. If I'm right, and if you turn on zombies in your build scheme, then getting that error should tell you which released object is the target of the method call. – Phillip Mills Apr 23 '15 at 20:07
  • Wow, zombies! Had almost forgotten about them since ARC. Unfortunately it didn't work: I still go strait to the same error (unrecognised selector, blah, blah, blah). – cfischer Apr 23 '15 at 20:15
  • Assuming the class in question is one you've written, an approach I've often followed is to temporarily add the method in question as a stub and then stick a breakpoint in it. This will at least tell you how your object is being sent the problematic method. – Rich Tolley Apr 23 '15 at 20:26
  • @RichTolley I tried that too. Unfortunately it didn't give much info either. It then complains of another unrecognised selector setNumberOfObjects:, then sectionNumber, etc... None of these show up in the docs. This is really annoying. – cfischer Apr 23 '15 at 20:35

1 Answers1

0

I'm not sure this will help to solve your underlying problem, but the following code finds all subclasses of NSObject answering to a certain selector:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        unsigned int classCount = 0;
        Class origin = [NSObject class];
        NSMutableArray *allSubclasses = [NSMutableArray array];
        Class *classes = objc_copyClassList(&classCount);
        for (int i = 0; i < classCount; i++) {
            Class superclass = classes[i];
            do {
                superclass = class_getSuperclass(superclass);
            } while (superclass && superclass != origin);

            if (superclass) {
                [allSubclasses addObject: classes[i]];
            }
        }
        free(classes);

        for (id class in allSubclasses) {
            // Put your selector here. I use "count" as an example
            if ([class instancesRespondToSelector:@selector(count)]) {
                NSLog(@"Class %@ responds to selector count.", NSStringFromClass(class));
            }
        }
        NSLog(@"%lu Classes were tested.", (unsigned long)[allSubclasses count]);
    }
    return 0;
}

Thanks go to this answer for finding all subclasses of NSObject. Also have a look at this article on Cocoa with Love on finding all subclasses of a specific class in Objective-C.

Community
  • 1
  • 1
MartinW
  • 4,966
  • 2
  • 24
  • 60