简体   繁体   English

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

[英]closure inside completion handler of URLSession.shared.dataTask

I have a call to a closure inside a URLSession.shared.dataTask task. 我在URLSession.shared.dataTask任务内调用了闭包。 The thing is that when I set a breakpoint inside my closure it won't finish executing. 关键是,当我在闭合中设置断点时,它不会完成执行。

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()

And this is how I call it. 这就是我所说的。

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()
        }
    }
}

I have set a break point inside the completion handler, and it seems that the error comes from the init of Comment class. 我已经在完成处理程序中设置了一个断点,看来该错误来自Comment类的初始化。

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

} }

The getImage and getQuery are same as the first code. getImage和getQuery与第一个代码相同。 I initiate a task and wait until I get the result using a semaphore. 我启动一个任务,然后等待直到使用信号量获得结果为止。

You say your closure won't finish executing and you also mentioned that you are using a semaphore somewhere in code you haven't posted. 您说您的关闭操作无法完成执行,您还提到您在尚未发布的代码中使用信号灯。 It is highly likely that you are using the semaphore incorrectly and that is blocking your thread. 您极有可能错误地使用了信号量,从而阻塞了线程。

There is nothing in the problem that I can see that warrants using a semaphore in the first place. 我能看到的问题没有什么可以证明的是首先要使用信号量。 By bringing in semaphores and exceptions, you seem to be making the code way more complex than necessary. 通过引入信号量和异常,您似乎使代码变得比必需的更加复杂。

I suggest you read up on how to unit test code and build up your logic a little at a time. 我建议您一次阅读一些有关如何对代码进行单元测试并逐步建立自己的逻辑的知识。 It looks like you are biting off more than you can chew at this time. 看来您现在正在咬的东西超出了您的咀嚼能力。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM