Ios 未保存整数的值

Ios 未保存整数的值,ios,swift,swift3,Ios,Swift,Swift3,我正在学习Swift,但我在ViewDidLoad中有一个Int类型的变量(Followers),我将该值设置为默认值0。然后我执行一个Json请求,返回1个数组,并将Followers的值设置为Json数组中的任意数字,即788。但是,当我在之后进行打印时,该值保持在0。这是我的代码,它会更有意义 override func viewDidLoad() { super.viewDidLoad() var followers = 0 // Sent

我正在学习Swift,但我在ViewDidLoad中有一个Int类型的变量(Followers),我将该值设置为默认值0。然后我执行一个Json请求,返回1个数组,并将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) 

          }

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

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

设置
NSSession
数据任务时,对
task.resume()
的调用会在网络请求发出之前立即返回

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

想象一下,你正在做饭,你让你的孩子出去买一袋面粉。你说“孩子,去给我拿些面粉。你回来后按公寓门上的蜂鸣器,我会按你进去的。”

然后你又开始做晚餐的其他部分,但你不希望在你告诉你的孩子去买面粉的那一刻,你会低头看柜台,面粉就会在那里。你知道你必须等到蜂鸣器响,然后你的孩子就会回来拿面粉

提交网络任务就是这样。调用
task.resume()
类似于您对面粉的请求。您提交了请求,但在请求完成处理之前,您仍在继续您正在做的事情。完成处理程序是一个蜂鸣器,它让你知道你的孩子带着面粉回来了

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

关键部分是DownloadManager.swift中的方法
downloadfileatrol()

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

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

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

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!
}
视图控制器有一个名为
handleDownloadButton()
的iAction函数。该职能:

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

在完成块中,将三行打印行放在
resume
之后,以及真实代码<代码>数据任务异步工作。PS:
对于Profiles中的Profiles
是胡说八道的,在读了邓肯的精彩答案后,我猜不会编译。我要说的是,不要让一系列的台词欺骗了你。序列是语法的派生。这里正确的端点是它的完成句柄。1) 对'task.resume()的调用立即返回。10号是什么意思?2) 我记得当我学习async时,也许现在:)return这个词的用法让我感到困惑,因为它是一个noob,现在也可能是OP,因为我们认为它意味着返回一个值,而它意味着返回队列以便开始另一个任务。3) 错别字:“四”对不起,这是试图使用苹果和ipad的反勾引号的副作用。出于某种原因,它经常将“`”符号转换为“第10个”。我修复了我的帖子。谢谢你的详细解释,现在它开始工作了。