Lizhen Hu
Lizhen Hu

Reputation: 944

How to check whether a protocol contains certain method programatically in Objective-C?

Is there any way to check whether a protocol contains certain method or whether a method belongs to certain protocol in Objective-C?

I don't think the redirected question is the same as mine. What I want is: [MyProtocol containsSelector:@selector(MySelector)]; Or [MySelector isMethodOfProtocol:@protocol(MyProtocol)];

Upvotes: 1

Views: 957

Answers (4)

malhal
malhal

Reputation: 30571

Here is a function I found Apple using:

#import <objc/runtime.h>

BOOL MHFProtocolHasInstanceMethod(Protocol *protocol, SEL selector) {
    struct objc_method_description desc;
    desc = protocol_getMethodDescription(protocol, selector, NO, YES);
    if(desc.name){
        return YES;
    }
    desc = protocol_getMethodDescription(protocol, selector, YES, YES);
    if(desc.name){
        return YES;
    }
    return NO;
}

Use like this:

- (id)forwardingTargetForSelector:(SEL)aSelector{
    if(MHFProtocolHasInstanceMethod(@protocol(UITableViewDelegate), aSelector)){
    ...

Upvotes: 1

Ayush Goel
Ayush Goel

Reputation: 3144

Here is a small code snippet I am using right now (thanks to Avi's answer above):

- (BOOL)isSelector:(SEL)selector
        ofProtocol:(Protocol *)protocol {
  unsigned int outCount = 0;
  struct objc_method_description *descriptions
  = protocol_copyMethodDescriptionList(protocol,
                                       YES,
                                       YES,
                                       &outCount);
  for (unsigned int i = 0; i < outCount; ++i) {
    if (descriptions[i].name == selector) {
      free(descriptions);
      return YES;
    }
  }
  free(descriptions);
  return NO;
}

You can move this to a category on NSObject too, if you use forwarding extensively.

Upvotes: 1

AnthoPak
AnthoPak

Reputation: 4391

If you know the name of the method, here is what you can do :

First set the delegate of the protocol. Then, check if the method belongs to the protocol as this :

if ([something.delegate respondsToSelector:@selector(someMethodToCheck)])

Upvotes: 2

Avi
Avi

Reputation: 7552

See the Objective-C runtime functions

Protocol *objc_getProtocol(const char *name)

struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *outCount)

The documentation can, at the time of this writing, be found here.

Upvotes: 2

Related Questions