ios - 协议(protocol)的 NSMethodSignature

标签 ios objective-c protocols

我正在使用此方法将方法分派(dispatch)给委托(delegate),不幸的是,我发现大多数时候 NSMethodSignature 为 nil,这是因为选择器来自协议(protocol)。我想知道哪种方法是正确的:

  1. 询问方法是否来自协议(protocol)
  2. 获取协议(protocol)方法的签名

[编辑]
根据 newacct 用户的观察,我的问题是不正确的,签名为 nil 是正常的,但不是因为它是一个协议(protocol),而是因为我针对错误的对象询问方法签名。 Self 在这种情况下它没有实现我想要分派(dispatch)的方法,它是使用和实现它们的委托(delegate)。

代码如下:

- (BOOL) dispatchToDelegate: (SEL) selector withArg: (id) arg error: (NSError*) err {
 NSMethodSignature *methodSig = [[self class] instanceMethodSignatureForSelector:selector];
 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSig]; 
[invocation setTarget:self.delegate]; 
BOOL result = NO; 
if([self.delegate respondsToSelector: selector]) {
        if(arg != NULL) {
            [invocation setArgument:&arg atIndex:2];      
            [invocation setArgument:&err atIndex:3];  
    }else {
        [invocation setArgument:&err atIndex:2];      

    }
    if ([NSThread isMainThread]) {
        [invocation invoke];        
    }
    else{
        [invocation performSelectorOnMainThread:@selector(invoke) withObject:nil waitUntilDone:YES];
    }
    [invocation getReturnValue:&result];
}
else
    NSLog(@"Missed Method");
return result;
}


[已更新答案] 我已经修改了在 Apple 邮件列表中找到的方法

- (NSMethodSignature *)methodSignatureForSelector:(SEL)inSelector
{
    NSMethodSignature *theMethodSignature = [super methodSignatureForSelector:inSelector];
    if (theMethodSignature == NULL)
    {
        struct objc_method_description theDescription = protocol_getMethodDescription(@protocol(GameCenterManagerDelegate),inSelector, NO, YES);
        theMethodSignature = [NSMethodSignature signatureWithObjCTypes:theDescription.types];
    }
    return(theMethodSignature);
}

它有效,但我会听从 bbum 的建议,代码变得非常复杂..希望尽快破解。

最佳答案

只是做:

if ([delegate respondsToSelector:@selector(someMethod:thatDoesSomething:)]) {
    dispatch_async(dispatch_get_main_queue(), ^{
        [delegate someMethod:foo thatDoesSomething:bar];
    }
}

对运行时进行神奇处理的诱惑很强烈,但这只会导致代码过于复杂,难以理解,速度变慢,而且并没有真正节省那么多代码行。重构也更难。

这显然不考虑返回值。但是,为此,您真的想要避免任何类型的阻塞调用。告诉主线程去做某事,然后让它在完成后安排一个 block 在适当的队列上执行。这将降低死锁的风险并使您的整体应用程序设计更加简单。

请注意,当从主线程调用时,上面的代码将导致 block 在下一次通过主事件循环时执行。这可能正是您想要的,因为它与并发情况的行为一致。

关于ios - 协议(protocol)的 NSMethodSignature,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17011197/

相关文章:

ios - 如何在协议(protocol)中声明泛型函数

ios - 如何在Unity3d中制作覆盖360度的平面

iphone - 在 iOS 上安装 JIRA Mobile Connect SDK

objective-c - 在 Objective-C 中,我如何测试对象类型?

objective-c - 对 '__objc_class_name_Fraction' 的 undefined reference

ios - 如何将符合具有关联类型的协议(protocol)的不同类型添加到集合中?

ios - 是否可以为 iBeacon 提示设置延迟时间?

ios - 我可以将 UILocalnotification 设置为每个月的最后一天重复吗?

objective-c - 如何在不同的类中设置委托(delegate)

ios 自定义委托(delegate)设置