//declaration
private var delegate: MyDelegate?
我应该使用这个
delegate!.result(data)
或者
delegate?.result(data)
在第一个版本中,我认为如果没有定义委托,程序将崩溃,但是在第二个版本中,如果没有定义委托,程序可能不会调用代理。
我的问题和关注是关于崩溃并立即让我知道我做错了(我想知道)或者是一个无声的错误(我忘了通过委托)这需要一些时间来弄明白,这是更好的方法?
答案 0 :(得分:3)
1)失败并非必须保持沉默:
if let myData = delegate?.result(data) {
// do something with myData
} else {
// handle the fact that the delegate didn't work
}
2)我认为由于强制解包!
而导致崩溃是一个坏主意:如果你在测试期间错过了它,它会在运行时将问题推迟给用户。相反,开发人员应该在编译时处理问题;通过Optionals,Swift可以帮助实现这一目标。
答案 1 :(得分:2)
这实际上取决于您的设计需求。通常delegate
是可选的,因此您的?
选项主要用于此模式。
也就是说,如果你真的想强制执行委托,你可以限制它在你指定的初始化程序中定义。
另一个选项是在从Interface Builder声明属性时在Xcode中看到的设计:隐式解包用于让init进程终止,然后解码器应该解码并分配所有出口。
因此,您会看到!
。在这种情况下,出口应始终存在,否则欢迎碰撞。
最后,我通常会使用一个可选的代表作为委托。但如果我想强制执行它,我会在初始化过程中强制执行它。这样你就不会忘记从一开始就传递一个具体的代表; - )
答案 2 :(得分:2)
就个人而言,我认为!.
是一个好主意的时代相当罕见。当然,你可能宁愿在生产中默默地失败,除非它是完全关键的。如果进度条绘图中的错误导致应用程序崩溃,那将是一种耻辱。如果操作对于您的应用程序正常运行至关重要并且至关重要,请对其进行适当的错误处理!也许告诉你的用户有什么不对劲。
作为妥协,你可以考虑这样的事情:
func assertOnNil<T>(msg: String, defaultVal: T)->T {
assertionFailure(msg)
return defaultVal
}
func assertOnNil(msg: String)->() {
assertionFailure(msg)
return
}
// this will assert in debug builds
let x = "foo".toInt()?.successor() ?? assertOnNil("Should have been a number",0)
// this will print 0 in release builds
println(x)
struct S {
func f()->() { println("S.f") }
}
let s: S? = nil
// this will assert in debug builds but fail silently on release
s?.f() ?? assertOnNil("do-nothing chain")
这可以适用于记录错误消息或改为抛出错误对话。