【问题标题】:How can I stop URLSessionTask when the Internet is disconnected?Internet 断开连接时如何停止 URLSessionTask?
【发布时间】:2017-11-26 08:45:07
【问题描述】:

我正在使用 URLSessionTask 来获取 url 的源代码。当互联网连接时,它工作得很好。

但是,当 Internet 断开连接时,我尝试构建。在模拟器中它是空白的,cpu 是 0%。影响的是My Tab Bar Controller 也丢失和空白(这是我的初始视图控制器)。好像这个任务正在连接中?

我想要从 dataTask 接收到的数据,所以我使用semaphore 使其同步。否则,由于 dataTask 是一个异步动作,我 get 是一个空字符串。

我该如何解决这个问题?

谢谢!

    let urlString:String="http://www.career.fudan.edu.cn/jsp/career_talk_list.jsp?count=50&list=true"
    let url = URL(string:urlString)

    let request = URLRequest(url: url!)
    let session = URLSession.shared
    let semaphore = DispatchSemaphore(value: 0)
    let dataTask = session.dataTask(with: request,
                                    completionHandler: {(data, response, error) -> Void in
                                        if error != nil{
                                            errorString = "Error!"
                                        }else{
                                            htmlStr = String(data: data!, encoding: String.Encoding.utf8)!
                                            //print(htmlStr)
                                        }

                                        semaphore.signal()
    }) as URLSessionTask

    //start task
    dataTask.resume()
    _ = semaphore.wait(timeout: DispatchTime.distantFuture)

【问题讨论】:

  • 你为什么使用信号量?
  • 我想要从dataTask收到的数据。否则,由于 dataTask 是一个异步操作,我得到的是一个空字符串。
  • 您不需要信号量:使用完成处理程序(回调)从异步操作中获取结果。
  • @Moritz 抱歉,当我尝试在完成处理程序(回调)中将数据放入 tableview 时。 Xcode 警告说“UITableView.dataSource 只能在主线程中使用”。它运行非常缓慢。如果我将 UITableView.dataSource 放在外面(回调),则视图只是空白.....它没有获取数据
  • @Moritz 它有效。你是我的英雄!非常感谢!

标签: ios swift url asynchronous semaphore


【解决方案1】:

更新:正如@Moritz 提到的,我终于使用完成处理程序(回调)。

func getforData(completion:  @escaping (String) -> ()) {
    if let url = URL(string: "http://XXXXX") {
        let request = URLRequest(url: url)
        let task = URLSession.shared.dataTask(with: request) {
            data, response, error in
            if let data = data, let getString = String(data: data, encoding: String.Encoding.utf8), error == nil {
                completion(getString)
            } else {
                print("error=\(error!.localizedDescription)")
            }
        }
        task.resume()
    }
}

在viewdidload中

override func viewDidLoad() {
    super.viewDidLoad()

    getforData { getString in
        // and here we get the "returned" value from the asynchronous task
        print(getString) //works well

        //tableview should work in main thread            
        DispatchQueue.main.async {
            self.newsTableView.dataSource = self
            self.newsTableView.delegate = self
            self.newsTableView.reloadData()
        }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-09
    相关资源
    最近更新 更多