4

If an object conforms to a certain protocol in Objective-C, is there a way to check if it conforms all the methods in that protocol. I would rather avoid explicitly checking each available method.

Thanks

Christian Gossain
  • 5,942
  • 12
  • 53
  • 85
  • 2
    Protocol methods are required by default, so if a class adopts a given protocol, it should implement all those methods that aren't marked `@optional`. – Caleb Feb 13 '14 at 23:14
  • 1
    @NoahWitherspoon I am not asking how to check for conformance to a protocol. I'm asking how to check if the methods in the actual protocol are all implemented. – Christian Gossain Feb 13 '14 at 23:19
  • 2
    Maybe by having a loop which calls respondsToSelector for each method of the protocol. And to have methods of the protocol, check this http://stackoverflow.com/questions/2094702/get-all-methods-of-an-objective-c-class-or-instance – Johnmph Feb 13 '14 at 23:20
  • 2
    This is not a duplicate. It's about checking whether classes actually implement the methods declared in a protocol. – Sebastian Feb 13 '14 at 23:46

1 Answers1

5

You can get all methods declared in a protocol with protocol_copyMethodDescriptionList, which returns a pointer to objc_method_description structs.

objc_method_description is defined in objc/runtime.h:

struct objc_method_description {
    SEL name;               /**< The name of the method */
    char *types;            /**< The types of the method arguments */
};

To find out if instances of a class respond to a selector use instancesRespondToSelector:

Leaving you with a function like this:

BOOL ClassImplementsAllMethodsInProtocol(Class class, Protocol *protocol) {
    unsigned int count;
    struct objc_method_description *methodDescriptions = protocol_copyMethodDescriptionList(protocol, NO, YES, &count);
    BOOL implementsAll = YES;
    for (unsigned int i = 0; i<count; i++) {
        if (![class instancesRespondToSelector:methodDescriptions[i].name]) {
            implementsAll = NO;
            break;
        }
    }
    free(methodDescriptions);
    return implementsAll;
}
Sebastian
  • 7,670
  • 5
  • 38
  • 50
  • 1
    Memory leak if the class doesn't implements all the methods of the protocol, add free(methodDescrptions); before return NO; or even better add a flag and break the loop instead when not found. – Johnmph Feb 14 '14 at 16:47
  • Guys one word...badass. Thanks Sebastian for this awesome answer and thanks @Johnmph for the follow up comment. – Christian Gossain Feb 14 '14 at 16:52
  • @Johnmph Thanks, good catch! I updated my answer to a single return statement. – Sebastian Feb 15 '14 at 03:43