swift - 在 catch 中引用 do 块中的变量
问题描述
我需要访问do
语句中的变量。它的行为是否类似于if
-else
语句,因为您不使用if
语句之外的变量?
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
override func loadView() {
do {
//let url = URL?("https://www.hackingwithswift.com")
let TECIONEXContent = try String(contentsOf: URL("https://www.hackingwithswift.com"))
} catch { print("error")}
//I need to access TECIONEXContent variable outside the do statement
// Error: Use of unresolved identifier 'TECIONEXContent'
var TECGrid = TECIONEXContent.components(separatedBy: "\n")
}
}
错误在最后一行,“未解析的标识符”。
解决方案
它的行为是否类似于
if
-else
语句,因为您不使用if
语句之外的变量?
是的。但就像if
-语句一样,您可以在-else
之前定义变量:do
catch
例如在if
-else
语句中:
let foo: String
if bar > 1 {
foo = "bigger than one"
} else {
foo = "one or smaller"
}
或者,在您的情况下:
let url = URL(string: "https://www.hackingwithswift.com")!
let contents: String
do {
contents = try String(contentsOf: url)
} catch {
print(error)
return
}
let grid = contents.components(separatedBy: "\n")
或者,您实际上并没有对错误消息做任何事情,您可以完全消除do
- catch
:
guard let contents = try? String(contentsOf: url) else {
print("error")
return
}
let grid = contents.components(separatedBy: "\n")
坦率地说,所有这些都说String(contentsOf:)
了,无论如何,使用可能不是最好的模式,因为它执行同步网络请求,如果主线程被阻塞,这可能会让操作系统“看门狗”进程毫不客气地杀死你的应用程序;即使没有发生这种情况,在网络请求正在进行时冻结应用程序也不是一个好的用户体验。通常我们会使用URLSession
:
let url = URL(string: "https://www.hackingwithswift.com")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard
let data = data,
let httpResponse = response as? HTTPURLResponse,
let string = String(data: data, encoding: .utf8) else {
print(error ?? "Unknown error")
return
}
guard 200 ..< 300 ~= httpResponse.statusCode else {
print("Expected 2xx response, but got \(httpResponse.statusCode)")
return
}
let grid = string.components(separatedBy: "\n")
DispatchQueue.main.async {
// use `grid` here
}
}.resume()
无关,但是:
惯例是以小写字母开头的变量名。
你实施了
loadView
. 我们很少这样做,而是实施viewDidLoad
,确保也调用super.viewDidLoad()
。如果你在操场上这样做,你显然也会设置
needsIndefiniteExecution
,如果你还没有。
因此:
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
performRequest()
}
func performRequest() {
let url = URL(string: "https://www.hackingwithswift.com")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard
let data = data,
let httpResponse = response as? HTTPURLResponse,
let string = String(data: data, encoding: .utf8) else {
print(error ?? "Unknown error")
return
}
guard 200 ..< 300 ~= httpResponse.statusCode else {
print("Expected 2xx response, but got \(httpResponse.statusCode)")
return
}
let grid = string.components(separatedBy: "\n")
DispatchQueue.main.async {
print(grid)
// use `grid` here
}
}.resume()
}
}
PlaygroundPage.current.liveView = ViewController()
PlaygroundPage.current.needsIndefiniteExecution = true
推荐阅读
- libgit2sharp - 'LibGit2Sharp.Core.NativeMethods' 的类型初始化程序引发了异常。“无法加载 DLL 'git2-572e4d8':
- javascript - 如何在javascript中实现可用作桌面滚动的触摸事件?
- xml - LibXML:“xmlns”属性被报告但不在 XML 输入文件中
- android - 如何使元素出现在布局的顶部
- ms-access - 为什么链接表管理器引用已删除的表?
- node.js - 如何从函数访问类的成员变量
- couchdb - 在超级账本结构中启动 couchdb
- ansible - 如何从同一块访问文件中的 ansible 块变量
- tensorflow - 对象检测的训练/测试拆分百分比 - 当前的建议是什么?
- python - python中有没有办法分配一个变量,使其始终指向其分配的右手边指向的内存?