用于调用方法的无法识别的选择器

时间:2013-02-26 09:12:23

标签: ios objective-c

- (NSDictionary*)convertMessage:(Message*)event
{
    // if this gets called then a derived class either didn't override this function or it called [super convertEvent:event]
    [self doesNotRecognizeSelector:_cmd];
    return nil;
}

我期待结果值为零。

-(void)calling{

 NSDictionary *dictionary  = [self convertMessage:evt];

}

但是它说无法识别的选择器发送到实例的错误块!跑步的时候!

2 个答案:

答案 0 :(得分:2)

[self doesNotRecognizeSelector:_cmd]的实现是抛出异常。所以预期的结果是提出异常。如果您希望返回nil,那么只需在方法中返回nil并执行 not 调用doesNotRecognizeSelector:

参考apple's doc

  

只要对象收到,运行时系统就会调用此方法   aSelector消息,它无法响应或转发。这个方法,在   转,引发NSInvalidArgumentException,并生成错误   消息。

     

任何doesNotRecognizeSelector:消息通常仅由   运行时系统。但是,它们可以在程序代码中用于防止   从继承的方法。例如,NSObject子类可能   通过重新实现它来包含a来放弃copy或init方法   doesNotRecognizeSelector:消息如下:

- (id)copy {
    [self doesNotRecognizeSelector:_cmd];
}
  

_cmd变量是传递给当前选择器的每个方法的隐藏参数;

     

在此示例中,它标识了复制方法的选择器。这个   代码阻止子类的实例响应副本   来自转发复制消息的消息或超类 - 尽管如此   respondsToSelector:仍然会报告接收者有权访问   复制方法。

     

如果覆盖此方法,则必须调用super或raise   你的结尾有NSInvalidArgumentException异常   实现。   换句话说,此方法不能正常返回;它必须始终导致抛出异常。

答案 1 :(得分:2)

延伸@ xlc0212的答案:

该方法的原始实现......

[self doesNotRecognizeSelector:_cmd];
return nil;

...从未期望达到return声明。正如@ xlc0212 doesNotRecognizeSelector所解释的那样会抛出异常,导致进程异常终止。

该实现的作者仅在其中放置return语句以使编译器警告静音。一个更现代,更容易混淆的方法是告诉clang无法达到代码中的这一点:

- (NSDictionary*)convertMessage:(Message*)event
{
    [self doesNotRecognizeSelector:_cmd];
    __builtin_unreachable();
}