我遇到了与
this post非常相似的问题,但我不完全理解答案.我已经创建了一个完成处理程序,但它似乎没有按预期工作.
func updateTeam(teamID: Int) { startConnection {NSArray,Int in //Do things with NSArray } } func startConnection(completion: (NSArray,Int) -> Void) { let url = URL(string: "http://www.example.com/path") var request : URLRequest = URLRequest(url: url!) request.httpMethod = "POST" let postString = "a=\(Int(teamInput.text!)!)" request.httpBody = postString.data(using: .utf8) let dataTask = URLSession.shared.dataTask(with: request) { data,response,error in print("anything") do { if let jsonResult = try JSONSerialization.jsonObject(with: data!,options: []) as? NSDictionary { self.teamResult = jsonResult print(jsonResult) } } catch let error as NSError { print(error.localizedDescription) } } dataTask.resume() completion(NSArray(object: teamResult),Int(teamInput.text!)!) }
dataTask语句中的任何内容似乎都没有运行,或者至少在我尝试使用所产生的数据之前它没有完成.这个完成处理程序有什么问题?
先感谢您!
解决方法
您的代码结构不正确.
URLSession创建异步运行的任务.您设置了一个任务,并传入一个完成块,或者设置一个委托.
在网络下载完成之前很久,task.resume()调用立即返回.
任务完成后,系统将调用您的完成处理程序(或您的委托,如果您使用委托样式).
请注意URLSessions的完成处理程序和委托调用是在后台线程上完成的.如果您为完成任务而执行任何UIKit调用,则需要在主线程上执行此操作.
正如@keithbhunter在他的评论中所说,你需要在你的任务的完成处理程序中调用你的完成处理程序.如果你在对主线程的调用中包装整个完成处理程序调用,那么它可能是最安全的:
func startConnection(completion: (NSArray,options: []) as? NSDictionary { self.teamResult = jsonResult print(jsonResult) //Use GCD to invoke the completion handler on the main thread dispatchQueue.main.async() { completion(NSArray(object: teamResult),Int(teamInput.text!)!) } } } catch let error as NSError { print(error.localizedDescription) } } dataTask.resume() }
请注意,teamInput.text的强制解包非常脆弱,如果teamInput.text为nil,或者无法转换为Int,则会崩溃.编写完成处理程序以获取从teamInput.text返回的数据和int值的选项,你会好得多.
func startConnection(completion: (NSArray?,Int?) -> Void) {
let value: Int? = teamInput.text != nil ? Int(teamInput.text!) : nil completion(NSArray(object: teamResult),value)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。