没有保存整数的IOS Swift值

时间:2016-11-25 19:46:10

标签: ios swift swift3

我正在学习Swift但我在ViewDidLoad中有一个Int类型的Variable(Followers),我将该值设置为默认值0。然后我做一个返回1个数组的Json Request,并将Followers的值设置为Json数组中788的数字。然而,当我之后进行打印时,值保持为0.这是我的代码,它会更有意义

 override func viewDidLoad() {
        super.viewDidLoad()
        var followers = 0

     // Sent HTTP Request

        sessionn.dataTask(with:requestt, completionHandler: {(data, response, error) in
            if error != nil {
                //    print(error)
            } else {
                do {

                    let parsedData = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:Any]
                    if let Profiles = parsedData["data"] as! [AnyObject]? {

                        for Profiles in Profiles {

                            if let follow = Profiles["followers"] as? Int {
                                self.followers =  follow
                              // The value here says 788
                                  print(self.followers)

                            }



                        }
                        DispatchQueue.main.async {

                        }
                    }

                } catch let error as NSError {
                    print(error)
                }

            }

        }).resume()


        print("Followers is")
     // The value here says 0 every time
        print(followers)
       // I have even tried
        print(self.followers) 

          }

正如你所看到的追随者变量设置为0当我执行我的HttpPost时,我可以看到当我有打印(self.followers)时,变量设置为788但是当我访问变量时循环它的值会回到0。当我通过构建应用程序学习Swift时,如何纠正这个错误。

1 个答案:

答案 0 :(得分:3)

您误解了异步代码的工作原理。

当您设置NSSession数据任务时,在发出网络请求之前,会立即回复task.resume()

您应该将处理响应的代码放在完成处理程序中。即使您在网络任务上调用resume后发生了The value here says 0打印语句,但尚未检索到数据。

想象一下,你正在做晚餐,然后你把孩子送去买一袋面粉。你说"孩子,给我一些面粉。当你回来时,按下公寓门上的蜂鸣器,我就会把你嗡嗡响。"

然后你回到烹饪晚餐的其他部分,但你不要指望你告诉你的孩子去面粉的那一刻,你会瞧不起柜台,面粉将是那里。你知道你必须要等到蜂鸣器发出嗡嗡声,然后你的孩子才会回来吃面粉。

提交网络任务就是这样。对task.resume()的调用类似于您对面粉的要求。您提交请求,但在请求完成处理之前,您继续执行您正在执行的操作。 完成处理程序正在运行的是蜂鸣器,让您知道您的孩子已经回来了。

编辑:

我在Github上创建了一个项目,演示了如何在URLSession中使用完成处理程序。该项目名为Async_demo(链接)

关键部分是DownloadManager.swift

中的方法downloadFileAtURL()

注意该函数如何将完成处理程序作为参数。该函数使用完成处理程序创建URLSession数据任务。在完成处理程序内,对于URLSession数据任务,downloadFileAtURL()函数调用传递给它的完成处理程序。它使用DispatchQueue.main.async()来调用主线程上的完成处理程序。

此演示项目使用URLSession数据任务,并明确禁用数据缓存,以便每次单击下载按钮时都会重新加载图像。

以下是DownloadManager.swift中的downloadFileAtURL()函数的代码:

func downloadFileAtURL(_ url: URL, completion: @escaping DataClosure) {

  //We create a URLRequest that does not allow caching so you can see the download take place
  let request = URLRequest(url: url,
                           cachePolicy: .reloadIgnoringLocalAndRemoteCacheData,
                           timeoutInterval: 30.0)
  let dataTask = URLSession.shared.dataTask(with: request) {
    data, response, error in

    //Perform the completion handler on the main thread
    DispatchQueue.main.async {
      //Call the copmletion handler that was passed to us
      completion(data, error)
    }
  }
  dataTask.resume()

  //When we get here the data task will NOT have completed yet!
}

视图控制器有一个名为handledDownloadButton()的IBAction函数。那个功能:

  • 禁用下载按钮并显示活动指示器视图。
  • 调用下载管理器的downloadFileAtURL()下载文件,传入完成处理程序。完成处理程序执行了大量的错误检查。如果一切正常,它会将结果数据转换为UIImage并将其安装在图像视图中,然后调用在图像上执行某些动画的方法,然后丢弃图像并重新启用下载按钮。