有些情况下您忘记设置值(因此它实际上是一个错误),并且使用强制解包运行程序可能会导致问题崩溃,这可以让您找到忘记设置值的错误你应该设置的。
从关于避免强制解包的帖子开始,总是提出强制解包会导致程序崩溃,因此这是一件坏事。当问题真正出现问题时崩溃会有什么不妥?
请举例说明强制展开可能是坏事。
(我并不是说强行打开适合所有事情。)
答案 0 :(得分:12)
只有当你作为程序员知道一个可选项永远不会是nil
的事实时,才应该使用强制解包(我还要包括强制转换) nil
代表了开发过程中代码中的一个明显错误(然后你希望它崩溃)。
有许多例子表明这种类型的强制展开是合适的。例子包括:
UITableView dequeueReusableCell
的电话(无意味着您的故事板中有错误)。显然还有很多其他情况需要强制解包,但你必须清楚地了解这些情况。
但是,有许多运行时决策会导致您无法保证选项,并且不应强制解包此类案例。
示例包括:
nil
结果。throw
或返回可选结果的任何API。事情可能会出错。错误发生。永远不要以为你会得到有效答案。代码防守。最后,开发人员具有适当的经验和理解选项如何工作,他们的意思,以及何时值可能或可能不是nil
的情况下的开发人员能够安全地使用强制解包适当。明智地使用它。
永远不要使用强制解包,因为Xcode建议让编译器满意。
答案 1 :(得分:1)
强制解包很糟糕,因为您的程序无法保证在执行时访问实际变量。当发生这种情况时,您的程序可能正在尝试对不存在的数字执行数学计算,并且您的应用程序将崩溃。在开发阶段,如果它崩溃了,你将能够缩小崩溃发生的原因,并在运行阶段确定它在运行时
例如,如果您从Web服务检索某种数字,您可能希望将此数字与本地数字进行比较,可能是版本号:
if let json = try? JSONSerialization.jsonObject(with: responseData, options: .allowFragments) as? [String: Any],
let serverAPIVersion:NSNumber = json["API_Version_Number"] as? NSNumber {
if self.currentAPIVersion.uintValue < serverAPIVersion.uintValue {
self.updateVersionWith(number: serverAPIVersion)
}
}
在上面的代码中,我们安全地从我们从服务器获得的JSON中展开"API_Version_Number"
。我们安全地展开,因为如果"API_Version_Number"
没有值,那么当我们尝试与当前版本进行比较时,程序会崩溃。
// This will crash if the server does not include "API_Version_Number in json response data
let serverAPIVersion:NSNumber = json["API_Version_Number"] as! NSNumber
在生产中,有些事情是您无法控制的(很多时候是服务器端问题)可能会导致无人居住的变量。这就是为什么最好有条件地解包以在代码中安全地访问值,以防止在执行时崩溃。
答案 2 :(得分:0)
如果程序确实有错误,那么崩溃程序没什么问题...如果你无法解决崩溃问题
但正如@ phillip-mills在评论中所说:
......在没有理解导致崩溃的原因的情况下使用强制解包的人问道
我们经常会看到一些例子,人们强行打开选项,出于某些意想不到的原因,它们不存在,并且在这种情况下尝试打开可选的&#34;优雅。
假设您有一个后端服务,它为您提供了一些JSON,您可以将其解析为模型对象并显示在视图中。
假设你有一个像这样的模型:
struct Person {
let firstName: String?
let lastName: String?
}
在UITableView
中,您使用人物对象填充一些单元格。有点像:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//dequeue your cell
//get your person element from some array
//populate
cell.firstNameLabel.text = person.firstName!
cell.lastNameLabel.text = person.lastName!
return cell
}
在某些时候,你最终可能会得到一个没有Person
的{{1}}(你可以说这是后端问题,依此类推等等......但是......&# 39; ll可能会发生:))如果您强行打开包装,您的应用程序将崩溃,因为它不应该是必要的。在这种情况下,你可以放弃优雅的展开
firstName
或者您可以使用 Nil Coalescing Operator
if let firstName = person.firstName {
cell.firstNameLabel.text = firstName
}
最后,正如@rmaddy在回答中所说的那样
强制解包是不好的,因为您的程序无法保证在执行时访问实际变量
您无法始终确保数据符合您的预期。
如果你完全确定你所操作的数据是有效的,也就是说,如果你已经安全地打开它,你实际上只能做一些操作。 。愚蠢不使用该选项:)
希望对你有所帮助。