我昨天发生了这个问题。我正在处理一段生产代码,该代码在崩溃信息的某个时刻崩溃了
password
但是,当我发现错误时,在尝试复制问题数小时后,在崩溃日志中找不到任何错误消息。该错误在XCode中显示为:
在解包可选值时意外发现nil
我的问题是,如何捕获生产代码中的nil-optional错误?
修改
为了向原始问题添加更多透视图,我在此示例代码中找到了问题:
//mobile text field
<input id="ember1245" class="ember-view ember-text-field mobile" type="text">
//password textfield
<input id="ember1247" class="ember-view ember-text-field placeholder" placeholder="New Password" type="password">
我应该这样做:
0 Goga 0x00000001000b90b8 function signature specialization <Arg[0] = Owned To Guaranteed, Arg[1] = Owned To Guaranteed> of Goga.NewViewController.emailButtonPressed (Goga.NewViewController)(ObjectiveC.UIButton) -> () (NewViewController.swift:0)
1 Goga 0x00000001000c0488 Goga.NewViewController.(emailButtonPressed (Goga.NewViewController) -> (ObjectiveC.UIButton) -> ()).(closure #2) (NewViewController.swift:872)
2 Goga 0x00000001000bd250 partial apply forwarder for reabstraction thunk helper from @callee_owned (@in ObjectiveC.UIAlertAction!) -> (@out ()) to @callee_owned (@owned ObjectiveC.UIAlertAction!) -> (@unowned ()) (NewViewController.swift:0)
答案 0 :(得分:5)
“捕获”“nil-optional error”的方法就是正确编写代码。不要滥用强迫展开和强制拆卸。
在这种特定情况下,只需阅读崩溃详细信息即可为我们提供一些信息:
1 Goga 0x00000001000c0488 Goga.NewViewController.(emailButtonPressed (Goga.NewViewController) -> (ObjectiveC.UIButton) -> ()).(closure #2) (NewViewController.swift:872)
在NewViewController.swift
的第872行附近的某处,你强行展开实际为nil
的东西(因此无法解开)。
解决方法是转到NewViewController.swift
的第872行,查找感叹号的任何出现,确定它是否为强制解包运算符,或者它是否为布尔运算符...以及它是否为强制解包运算符,使用Swift的可选绑定设计模式修复它。
可能你正在做这样的事情:
let foo = bar!
或许某处bar
声明如下:
var bar: AnyObject!
然后它永远不会被初始化(或者在某些时候被设置为nil
),然后因为它被隐式解开,你做的是这样的事情:
let foo: AnyObject = bar
这些都可能导致您正在查看的错误。
是的,在编写代码时,隐式解包的选项和强制解包可以使事情稍微方便一些,但最终,所有这意味着你遇到了这些问题,你最终必须追查这些问题。当Swift拥有大量工具来确保nil
安全时,没有必要这样做。
答案 1 :(得分:0)
在处理期权时,您应该使用if语句有条件地解开它们。
var ctrl = angular.element(event.currentTarget).controller('mdChips');
if(ctrl !== undefined){
var selectedChip = ctrl.items[ctrl.selectedChip];
}