ios - defer 语句的不同行为
问题描述
我在注销按钮上有代码,我正在使用defer
语句。
我想知道defer
在操作方法范围内更改语句代码的位置时。
- 我
defer
在方法的末尾添加了语句,它向我显示警告。
作用域结束前的“defer”语句总是立即执行;替换为“do”语句以消除此警告
代码:
override func sendButtonTapped(sender: Any) {
self.deleteCoreData()
self.clearUserDefaults()
// Clear view context
AppDelegate.shared.persistentContainer.viewContext.reset()
....
....
// Call after all code execution completed in this block's Scope
defer {
// Set isUserLoggedIn and change root view controller.
UserDefaults.Account.set(false, forKey: .isUserLoggedIn)
AppDelegate.shared.setRootViewController()
}
}
- 然后,我
defer
在方法开始时添加了语句,它什么也没显示。
代码:
override func sendButtonTapped(sender: Any) {
// Call after all code execution completed in this block's Scope
defer {
// Set isUserLoggedIn and change root view controller.
UserDefaults.Account.set(false, forKey: .isUserLoggedIn)
AppDelegate.shared.setRootViewController()
}
self.deleteCoreData()
self.clearUserDefaults()
// Clear view context
AppDelegate.shared.persistentContainer.viewContext.reset()
....
....
}
谁能解释一下defer
语句到底发生了什么?
解决方案
总而言之,该defer
语句将在您所在范围的末尾执行。(.apple doc:https ://docs.swift.org/swift-book/ReferenceManual/Statements.html#grammar_defer-statement )
来自苹果文档
func f() {
defer { print("First defer") }
defer { print("Second defer") }
print("End of function")
}
f()
// Prints "End of function"
// Prints "Second defer"
// Prints "First defer"
该defer
语句允许您定义将在您想要完成的其余操作之后执行的操作,即在范围的末尾。
警告也非常明确,考虑到您将defer
语句放在范围的末尾,它没有任何用途:
func f() {
print("TIC")
defer { print("TAC") } // will be print at the end of the function
}
f()
// Prints "TIC"
// Prints "TAC""
这与:
func f() {
print("TIC")
print("TAC") // no defer, same result
}
f()
// Prints "TIC"
// Prints "TAC""
走得更远
那为什么警告会建议你do
阻止?其实前面的两个例子并不是100%一样的,当你使用defer
语句时,它会创建自己的作用域
func f() {
// here you are in the scope of the `f()` function
print("TIC")
defer {
// here you are the scope of the `defer` statement
print("First defer")
}
}
手动创建范围最接近的方法是do
语句
func f() {
// here you are in the scope of the `f()` function
print("TIC")
do {
// here you are the scope of the `do` statement
print("First defer")
}
}
来自苹果文档
do 语句用于引入新的范围,并且可以选择包含一个或多个 catch 子句,其中包含与定义的错误条件匹配的模式。在 do 语句范围内声明的变量和常量只能在该范围内访问。
如果您想了解有关范围的更多信息,这里有一些讲座:https ://andybargh.com/lifetime-scope-and-namespaces-in-swift/
本质上,对象范围定义了我们程序中可以访问项目的区域。
推荐阅读
- javascript - 在样式组件道具上使用反向选择器模式时不起作用?
- html - 如何使用 JScript 从 HTML 网页自动化 Excel?
- java - API 调用似乎在 React 中不起作用
- reactjs - 如何更改 Material-UI 线性进度条不确定的动画速度?
- android - 将项目导入 Android Studio。同步因“未知原因”而失败。有什么潜在的原因吗?
- java - 如何解决错误“找不到符号”和“')'预期”?
- python - TensorFlow 图形数学
- mod-wsgi - Apache 配置:“客户端被服务器配置拒绝”
- javascript - 尝试使用 sweetalert2 从 javascript 上传时出现“未定义的数组键‘文件’”
- javascript - 使用 Javascript 在共享驱动器 (Google Drive API) 中创建文件夹