2
- (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];

}

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

4

2 回答 2

2

要扩展@xlc0212 的答案:

该方法的原始实现...

[self doesNotRecognizeSelector:_cmd];
return nil;

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

实现的作者只是将return语句放在那里以使编译器警告静音。一种更现代、更容易做到这一点的方法是告诉 clang 无法达到代码中的这一点:

- (NSDictionary*)convertMessage:(Message*)event
{
    [self doesNotRecognizeSelector:_cmd];
    __builtin_unreachable();
}
于 2013-02-26T09:24:46.877 回答
2

的实现[self doesNotRecognizeSelector:_cmd]是抛出异常。所以预期的结果是引发异常。如果您期望返回 nil,则只需在方法中返回 nil 并且不要调用doesNotRecognizeSelector:

参考苹果的文档

每当对象接收到它无法响应或转发的 aSelector 消息时,运行时系统就会调用此方法。反过来,此方法引发 NSInvalidArgumentException,并生成错误消息。

任何doesNotRecognizeSelector:消息一般只由运行时系统发送。但是,它们可以在程序代码中使用以防止方法被继承。例如,一个 NSObject 子类可能会放弃 copy 或 init 方法,方法是重新实现它以包含一个 doesNotRecognizeSelector: 消息,如下所示:

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

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

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

如果你重写这个方法,你必须在你的实现结束时调用 super 或引发一个 NSInvalidArgumentException 异常。 换句话说,这个方法不能正常返回;它必须总是导致抛出异常。

于 2013-02-26T09:18:27.393 回答