【发布时间】:2019-11-16 17:09:26
【问题描述】:
我有一个使用UIImagePickerController 选择图像的应用。然后将该图像传递给 API 函数。一旦该功能完成,我将使用委托将结果传递给带有结果的模态显示控制器。但是,模态控制器出现在完成块之前,并且我的错误 AlerViewController 警报永远不会被调用。
API 在后台线程中运行,我已在主线程上设置完成(因为它更新 UI - 呈现模态控制器)但它在完成完全执行之前被调用。
代码如下;
API 请求
func searchImage(with image: UIImage, to viewController: UIViewController, success: @escaping([ViImageResult]?) -> Void) {
var results = [ViImageResult]()
let params = ViUploadSearchParams(image: image)
ViSearch.sharedInstance.uploadSearch(params: params, successHandler: { (data : ViResponseData?) -> Void in
guard let data = data else { return }
if data.result.isEmpty {
AlertViewController.noResultsFound(viewController: viewController)
return
} else {
if data.hasError {
AlertViewController.dataError(viewController: viewController)
return
} else {
for response in data.result {
results.append(response)
}
DispatchQueue.main.async {
success(results)
}
}
}
}, failureHandler: {
(error) -> Void in
AlertViewController.dataError(viewController: viewController)
})
}
控制器
var selectedImage: UIImage? {
didSet {
guard let selectedImage = selectedImage else { return }
ViSearchSDKService.shared.searchImage(with: selectedImage, to: self) { (results) in
guard let results = results else { return }
if self.resultsDelegate != nil {
self.resultsDelegate?.recievedResults(recievedResults: results)
}
}
let resultsController = ResultsViewController()
self.resultsDelegate = resultsController
let navigationController = UINavigationController(rootViewController: resultsController)
navigationController.modalPresentationStyle = .overFullScreen
DispatchQueue.main.async {
self.present(navigationController, animated: true, completion: nil)
}
}
}
在 API 请求中,我所有的 AlertViewController 函数都在主线程上调用,然后从请求中返回。成功块也在主线程上调用。
我在这里做错了什么?...
更新
我不太清楚为什么会这样,但它可以满足我的一切需求。我已将 API 请求移到了
之外的另一个函数中var selectedImage: UIImage? {
didSet {
在我的控制器中。
新的工作代码
var selectedImage: UIImage? {
didSet {
guard let selectedImage = selectedImage else { return }
self.searchImage(with: selectedImage)
}
}
func searchImage(with image: UIImage) {
ViSearchSDKService.shared.searchImage(with: image, to: self) { (results) in
guard let results = results else { return }
let resultsController = ResultsViewController()
self.resultsDelegate = resultsController
if self.resultsDelegate != nil {
self.resultsDelegate?.recievedResults(recievedResults: results)
}
let navigationController = UINavigationController(rootViewController: resultsController)
navigationController.modalPresentationStyle = .fullScreen
DispatchQueue.main.async {
self.present(navigationController, animated: true, completion: nil)
}
}
}
【问题讨论】:
-
我并没有真正关注您的问题,但那些
guard let results = results else { return }和guard let data = data else { return }行是在没有任何调试/错误处理的情况下可能发生的路径。也许在里面放一个debugPrint,看看它是否走那条路¯_(ツ)_/¯ -
我的控制器代表在任务完全完成之前被调用。我想我需要为 for 循环添加一个调度组。
-
data.result 中的响应
-
你有没有设置一个断点,看看它是否到达了代码的那部分?
-
你甚至不需要 for 循环...
results.append(contentsOf: data.results)developer.apple.com/documentation/swift/array/3126941-append ,绝对不需要任何访问控制或等待它。
标签: swift grand-central-dispatch dispatch completionhandler