出于某种原因,我想将所有 UITableViewDelegate 方法转发到另一个对象。这是我编写的代码,但是因为 UITableViewDelegate 中有很多方法。我必须为每个方法编写许多 if else 比较。
- (id)forwardingTargetForSelector:(SEL)aSelector
{
NSString* selector = NSStringFromSelector(aSelector);
if ([selector isEqualToString:@"tableView:didSelectRowAtIndexPath:"])
{
return self.outDelegate;
}
else
{
return [super forwardingTargetForSelector:aSelector];
}
}
我认为有一个更好的解决方案可以做到这一点。我可以像下面这样做吗,如何测试选择器是否在协议(protocol)中定义
- (id)forwardingTargetForSelector:(SEL)aSelector
{
if (**aSelector is Defined in aProtocol**)
{
return self.outDelegate;
}
else
{
return [super forwardingTargetForSelector:aSelector];
}
}
最佳答案
您可以使用 protocol_copyMethodDescriptionList
获取协议(protocol)中方法的 C 数组:
int numOfMethods;
struct objc_method_description * method_description_list;
method_description_list = protocol_copyMethodDescriptionList(@protocol(protocolName),
YES, YES, &numOfMethods)
数组中的描述数量现在存储在 numOfMethods
变量中。然后,您可以迭代此数组,并使用 ==
检查每个方法的选择器是否等于当前选择器,而不是将选择器转换为字符串:
for (int i=0; i<numOfMethods; i++) {
if (aSelector == method_description_list[i].name)
//forward to other delegate
else
return [super forwardingTargetForSelector:aSelector];
}
请注意,使用完毕后,您需要执行 free(method_description_list)
来回收它占用的内存。
每次调用 forwardingTargetForSelector:
时都没有必要重新创建和释放它,因此您可能需要执行一些操作,例如将其转换为 iVar 并在 init
中创建它>,然后在 dealloc
中释放
它,因为协议(protocol)在该对象的生命周期内不太可能改变
关于ios - 如何判断一个选择器是否包含在objc中的一个协议(protocol)中?谢谢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29536651/