在Objective-C中是否有任何方法可以检查协议是否包含特定方法或方法是否属于特定协议?
我不认为redirected question与我的相同。我想要的是:
[MyProtocol containsSelector:@selector(MySelector)];
要么
[MySelector isMethodOfProtocol:@protocol(MyProtocol)];
请参见Objective-C运行时函数
Protocol *objc_getProtocol(const char *name)
struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p, BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *outCount)
在撰写本文时,可以找到文档here。
如果您知道方法的名称,则可以执行以下操作:
首先设置协议的委托人。然后,检查该方法是否属于协议,如下所示:
if ([something.delegate respondsToSelector:@selector(someMethodToCheck)])
这里是我正在使用的一个小代码段(由于上面的Avi's answer:]
- (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;
}
如果您广泛使用转发,也可以将其移至NSObject
上的类别。
这里是我发现苹果使用的功能:
#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;
}
像这样使用:
- (id)forwardingTargetForSelector:(SEL)aSelector{
if(MHFProtocolHasInstanceMethod(@protocol(UITableViewDelegate), aSelector)){
...