经过一段时间后,我发现无法识别的选择器被发送到实例异常。当我得到这个,我想跳过它,我的应用程序应该工作。
然而我不知道该怎么抓。因为这没有抓住:
@property(nonatomic,retain) UIButton *button;
@try{
if(button.currentBackgroundImage == nil){//rises exception
}
}@catch(NSException *e){
}
我怎么能处理这个?
感谢。
答案 0 :(得分:6)
我经常使用和查看的技术是:检查对象是否响应选择器,而不是捕获异常:
if(![button respondsToSelector:@selector(currentBackgroundImage)] || button.currentBackgroundImage == nil) {
// do your thing here...
}
答案 1 :(得分:2)
如果您收到此异常,则表示存在设计缺陷,代码中存在错误。通过忽略异常来修补它不是正确的做法。尝试确定将错误消息发送到错误对象的原因。您的代码将变得更强大和可维护。
此外,有时您在对象最初属于正确类型时会遇到此异常,但在被解除分配的过程中处于中途。小心!
如果您仍想绕过异常,请阅读Apple的文档,其中介绍了在运行时将消息绑定到方法实现的多步骤过程。至少有两个地方可以通过覆盖NSObject的默认行为来捕获它。
答案 2 :(得分:0)
我理解答案告诉您要防止使用无法识别的选择器,因为这是首选方法。
但是在您没有该选项的情况下(例如,在我的情况下,Cocoa内部在调用堆栈中更糟),您确实可以在尝试时捕获无法识别的选择器。
概念证明代码:
// Do a really bad cast from NSObject to NSButton
// to get something to demonstrate on
NSButton *object = (NSButton*)[[NSObject alloc] init];
@try{
// Log the description as the method exists
// on both NSObject and NSButton
NSLog(@"%@", [object description]);
// Send an unrecognized selector to NSObject
[object bounds];
} @catch(NSException *e){
NSLog(@"Catch");
} @finally {
NSLog(@"Finally");
}
// Print the description to prove continued execution
NSLog(@"Description again: %@", [object description]);
输出:
2019-02-26 14:11:04.246050+0100 app[46152:172456] <NSObject: 0x60000000a6f0>
2019-02-26 14:11:04.246130+0100 app[46152:172456] -[NSObject bounds]: unrecognized selector sent to instance 0x60000000a6f0
2019-02-26 14:11:04.246226+0100 app[46152:172456] Catch
2019-02-26 14:11:04.246242+0100 app[46152:172456] Finally
2019-02-26 14:11:04.246258+0100 app[46152:172456] Description again: <NSObject: 0x60000000a6f0>
如您所见,异常仍然记录在控制台中,但是代码执行仍在继续。