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) 
} 
+0

您必须在闭包的范围外声明一个变量,并将闭包内的值赋值给该变量。但是,由于您正在处理网络请求,因此闭包实际上是一个完成处理程序,只有在异步请求完成后才会立即返回,因此在完成块之后立即打印值仍然无效。查看Swift中完成处理程序和异步函数的工作方式 –

+0

这是一个计时问题。 'print(pic)'语句是在'dataTask'的异步完成处理程序关闭有机会运行之前执行的。底线,请记住闭包异步运行,所以不要试图在闭包之外立即使用结果。通常你会从封闭内发送UI更新到主队列中,或者更好的是自己采用完成处理器模式。 – Rob

假设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

只需添加。抱歉。 –