Swift3 - 如何访问变量在封闭
问题描述:
我试图访问变量pic
在请求后,但它在封闭,这就是为什么print(pic)
不起作用。Swift3 - 如何访问变量在封闭
有人会如何去访问这个?
guard let url = URL(string: "myurl") else{ return }
var pic = ""
let session = URLSession.shared
session.dataTask(with: url) { (data, response, error) in
if let response = response {
print(response)
}
if let data = data {
print(data)
do {
let json = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? NSDictionary
if let parseJSON = json {
pic = parseJSON["picture"] as! String
print(json!)
}
} catch {
print(error)
}
}
}.resume()
print(pic)
}
答
假设PIC的图像你会被加载到一个UIImageView
:
您可以添加一个活动指示灯您的ImageView。然后当你打电话给你的功能下载图片只需添加:
guard let url = URL(string: "myurl") else{ return }
activityIndicator.isHidden = false
activityIndicator.startAnimating()
用户将知道下载正在进行中。完成后,
DispatchQueue.main.async {
activityIndicator.isHidden = true
activityIndicator.stopAnimating()
myImageView.image = UIImage(named: "pic")
}
}.resume
在主队列上调度将立即更新用户界面。
+0
如果您要从'dataTask'完成处理程序关闭中更新UI,请确保将这些UI更新分派给主队列。 – Rob
+0
只需添加。抱歉。 –
您必须在闭包的范围外声明一个变量,并将闭包内的值赋值给该变量。但是,由于您正在处理网络请求,因此闭包实际上是一个完成处理程序,只有在异步请求完成后才会立即返回,因此在完成块之后立即打印值仍然无效。查看Swift中完成处理程序和异步函数的工作方式 –
这是一个计时问题。 'print(pic)'语句是在'dataTask'的异步完成处理程序关闭有机会运行之前执行的。底线,请记住闭包异步运行,所以不要试图在闭包之外立即使用结果。通常你会从封闭内发送UI更新到主队列中,或者更好的是自己采用完成处理器模式。 – Rob