从不同的 VC 访问时,带有完成处理程序的 API 调用函数崩溃
Posted
技术标签:
【中文标题】从不同的 VC 访问时,带有完成处理程序的 API 调用函数崩溃【英文标题】:API call function with completion handler crashes when accessed from different VC 【发布时间】:2017-11-28 11:26:33 【问题描述】:有人可以修复我的函数代码吗,因为我创建了一个 API 调用函数,它将获取我类中特定对象的 imageURL 并在第二个视图控制器中显示结果。我创建了自定义完成处理程序,以便仅在完成 imageURL 的下载时执行来自第二个 VC 的代码。
但是,当我在第二个视图控制器中测试此功能以打印它已到达的数据时,我在打印语句行上遇到了崩溃。
这是我在模型类文件中的 API 调用函数的代码:
func parseImageData(finished: () -> Void)
let urlPath = _exerciseURL
let url = URL(string: urlPath!)
let task = URLSession.shared.dataTask(with: url!) (data, response, error) in
if error != nil
print("Error while parsing JSON")
else
do
if let data = data,
let fetchedImageData = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? [String:Any],
let images = fetchedImageData["results"] as? [[String: Any]]
for eachImage in images
let imageUrl = eachImage["image"] as! String
self._imageUrl = URL(string: imageUrl)
print(self._imageUrl)
catch
print("Error while parsing data.")
task.resume()
finished()
在第二个视图控制器中,我只是在测试是否可以访问代码块:
override func viewDidLoad()
super.viewDidLoad()
exercise.parseImageData()
print("Arrived Here?") // I am getting crash on this line moving to debug navigator.
【问题讨论】:
请设置完成处理程序完成()(之前或之后)打印(self._imageUrl)并让我知道它是否工作? 崩溃说什么? 您是否在parseImageData
完成处理程序中执行任何 UI 更新?
显然在 print 语句之前移动 finished() 迫使我将函数参数更改为 @escaping 但它可以工作,现在它可以访问第二个 VC 中的代码块。我仍然不明白怎么做,因为它似乎表明在任务中间完成,但谢谢你的帮助。
在您的代码中,finished()
在代码执行后调用,而不是在响应到来后调用。这就是为什么将它移动到封闭内的原因。大括号中URLSession.shared.dataTask(with: url!)
之后的部分在您收到响应/错误后执行
【参考方案1】:
如果崩溃说明了force unwrapping nil
,那可能是因为let task = URLSession.shared.dataTask(with: url!)
正在展开url
,这是nil
此处的可选变量。
但是无论如何,您的完成处理程序在错误的位置被调用,请尝试将您的 finished()
回调放入 do
语句中。因为finished
在你调用exercise.parseImageData()
的那一刻就被执行了
if error != nil
print("Error while parsing JSON")
else
do
if let data = data,
let fetchedImageData = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves) as? [String:Any],
let images = fetchedImageData["results"] as? [[String: Any]]
for eachImage in images
let imageUrl = eachImage["image"] as! String
self._imageUrl = URL(string: imageUrl)
print(self._imageUrl)
finished()
catch
print("Error while parsing data.")
【讨论】:
我移动了它并开始工作,但我不知道为什么在视图控制器中更新图像需要大约 10 秒。 您需要将图像视图更新分派到主队列。以上是关于从不同的 VC 访问时,带有完成处理程序的 API 调用函数崩溃的主要内容,如果未能解决你的问题,请参考以下文章