unrecognized selector的异常

unrecognized selector的异常之前的三次拯救:

1. Method resolution

objc运行时会调用+resolveInstanceMethod:或者
+resolveClassMethod:,让你有机会提供一个函数实现。
如果你添加了函数,那运行时系统就会重新启动一次消息发送的过程,
否则 ,运行时就会移到下一步,消息转发(Message Forwarding)。

2. Fast forwarding

如果目标对象实现了-forwardingTargetForSelector:,
Runtime 这时就会调用这个方法,
给你把这个消息转发给其他对象的机会。
只要这个方法返回的不是nil和self,整个消息发送的过程就会被重启,
当然发送的对象会变成你返回的那个对象。
否则,就会继续Normal Fowarding。
这里叫Fast,只是为了区别下一步的转发机制。
因为这一步不会创建任何新的对象,
但下一步转发会创建一个NSInvocation对象,所以相对更快点。

3. Normal forwarding

这一步是Runtime最后一次给你挽救的机会。
首先它会发送-methodSignatureForSelector:
消息获得函数的参数和返回值类型。
如果-methodSignatureForSelector:返回nil,
Runtime则会发出-doesNotRecognizeSelector:
消息,程序这时也就挂掉了。
如果返回了一个函数签名,Runtime就会创建一个NSInvocation对象并发送-forwardInvocation:消息给目标对象。