ios - URLSession.shared.dataTask 的完成处理程序内的闭包

标签 ios swift asynchronous nsurlsession

我在 URLSession.shared.dataTask 任务中调用了一个闭包。 问题是,当我在闭包中设置断点时,它不会完成执行。

func query(url: String, args: [String:String], completion: @escaping (_ data: Data) -> Void) {
// Create request url in order to query API.
let url = makeGetRequestUsing(url: url, args: args)
let task = URLSession.shared.dataTask(with: url!) { data, response, error in
    guard let data = data, error == nil else {
        print("error:", error ?? "")
        return
    }
    completion(data)
}

task.resume()

我就是这么调用它的。

self.comments = []
api.query(url: url, args: args) { data in
    let jsonData = try! JSONSerialization.jsonObject(with: data)
    print(String(data: data, encoding: .utf8))
    if let jsonArray = jsonData as? [[String: Any]] {
        // Create comments from the json received.
        for i in 0..<jsonArray.count {
            do {
                self.comments.append(try Comment(json: jsonArray[i]))
            } catch {
                print(error)
            }
        }
        DispatchQueue.main.async {
            self.refreshComments()
        }
    }
}

我在完成处理程序中设置了一个断点,看来错误来自Comment类的init。

init(json: [String: Any]) throws {
// Get the comment text.
guard let comment = json[Comment.commentText] as? String else {
  throw SerializationError.missing(Comment.commentText)
}

// Get userImage.
guard let userId = json[Comment.userId] as? Int,
  let userImage = APIData.shared.getImage(url: "/userImageForId", args: ["id": String(userId)]) else {
    throw SerializationError.missing(Comment.userId)
}

// Get userename.
guard let resp = APIData.shared.getQuery(url: "/userNameForId", args: ["id": String(userId)]) as? [String: String],
  let username = resp[Comment.username] else {
    throw SerializationError.missing(Comment.username)
}

self.comment = comment
self.username = username
self.userImage = userImage

}

getImage和getQuery与第一个代码相同。我启动一个任务并等待,直到使用信号量获得结果。

最佳答案

您说您的闭包将无法完成执行,并且您还提到您在未发布的代码中的某处使用了信号量。您很可能错误地使用了信号量,从而阻塞了您的线程。

我认为这个问题中没有任何东西可以保证首先使用信号量。通过引入信号量和异常,您似乎使代码变得比必要的更加复杂。

我建议您阅读如何对代码进行单元测试并一次一点地构建您的逻辑。看起来你现在是贪多嚼不烂。

关于ios - URLSession.shared.dataTask 的完成处理程序内的闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43505232/

相关文章:

swift - NSSearchField TextDidChange 的方法是什么?

ios - 如何在 Swift 2.2 中使用 ResearchKit 在自定义事件步骤中禁用下一步按钮?

python - Python 3.4 中的 `async for`

ios - 通知观察者被多次调用,即使观察者被移除

java - Android AsyncTask异常和onPostExecute

objective-c - 循环中的异步 block

ios - 我们是否总是需要在闭包中调用完成处理程序?

ios - 使用 Storyboard ios5 时从 View Controller 移动到选项卡栏 Controller

ios - NSTemporaryDirectory 在 RAM 中吗?

ios - 保存视频到图库,获取视频存放到图库的路径