类对象在接收到无法解读的消息时,会出现unrecognized selector sent to instance的crash
unrecognize selector崩溃例如这种情况:
WTPerson *p = [WTPerson new];
WTBird*bird = (WTBird*)p;
[bird fly];
WTBird 有一个fly的实例方法 而WTPerson是没有的.unrecognized selector也就是消息被发送给了不能处理它的对象。
我们可以在运行时做一些动作 来帮助对象处理这种无法解读的消息
1.通过重写+(BOOL)resolveInstanceMethod:(SEL)sel 或+(BOOL)resolveClassMethod:(SEL)sel方法(当消息方法是实例方法时调用前者,当消息方法为类方法时,调用后者),在其中对类使用用 class_addMethod 添加方法,以此防止crash。
当类遇到不能处理的消息时,会调用上面那两个方法,sel既不能响应的方法,也就是消息,这个方法返回一个bool值
2. 使用- (id)forwardingTargetForSelector:(SEL)aSelector方法,这个方法返回一个id类型,可以在此方法中,将未知消息传递给另一个类对象
3.方法-(void)forwardInvocation:(NSInvocation *)anInvocation,参数 anInvocation 中包含未处理消息的各种信息(selector\target\参数...)。在这个方法中,可以把 anInvocation 转发给多个对象. 在调用forwardInvocation:之前会调用- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector方法来获取这个选择子的方法签名,然后在-(void)forwardInvocation:(NSInvocation *)anInvocation方法中你就可以通过anInvocation拿到相应信息做处理.
最后 如果仍然没能处理掉这个未知消息,则会调用NSObject 的-(void)doesNotRecognizeSelector:(SEL)aSelector方法.
网友评论