【问题标题】:ViewController as Popup While Wait for Dispatch SemaphoreViewController 在等待调度信号量时作为弹出窗口
【发布时间】:2017-09-22 19:24:31
【问题描述】:

我在发出 URL JSON 请求时使用 Dispatch Semaphore 进行等待,此等待可能需要一段时间。为了克服这种情况,我决定创建一个新视图,并在发出请求时将其显示为弹出窗口。为此,我使用了以下代码:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    self.showPopUp() 
    let semaphore = DispatchSemaphore(value: 0)

    self.api.requestMedicationsByReagent(method: 1, ean: "", hash: medHash!, gen: generic) { output in
        semaphore.signal()
        self.objects = output
    }
     // Thread will wait here until async task closure is complete
     let _ = semaphore.wait(timeout: DispatchTime.distantFuture)
}

showPopUp 的作用:

func showPopUp() {
    let popOverVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "loadingPopUp") as! PopUpViewController

    self.addChildViewController(popOverVC)
    popOverVC.view.frame = self.view.frame
    self.view.addSubview(popOverVC.view)
    popOverVC.didMove(toParentViewController: self)
}

问题在于,showPopUp 函数仅在发出请求后才被调用,并且弹出视图只是在屏幕上闪烁。在请求之前如何调用它?

【问题讨论】:

    标签: ios swift view popup dispatch


    【解决方案1】:

    问题是wait 将阻塞主线程,直到信号量执行signal,从而阻塞进程中的 UI(以及其他事情)。

    我建议您完全消除该信号量。 (无论如何,这是一个非常糟糕的做法。)只需在启动异步请求之前显示弹出窗口并在完成处理程序中将其关闭(如果您的完成处理程序没有运行,请确保将其分派到主队列主线程)。

    【讨论】:

    • 删除信号量的问题是我在它之后执行了一个segue。如果我确实删除了,segue 会在没有设置 self.objects = output 的情况下执行,我需要这样做,因为我将在另一个视图控制器中使用此信息
    • 所以从单元格中移除segue,取而代之的是视图控制器之间的segue。然后,当您在完成处理程序中删除弹出框时,您也可以以编程方式执行 segue。但是,如果您在主队列上等待,您可能会影响需要主队列的任务的操作,您会引入死锁风险,如果在不合时宜的时间完成,iOS 看门狗进程可能会杀死您的应用程序。通常,您永远不想阻塞主线程。
    • 谢谢,这很好用!现在我想弄清楚为什么我在被分割的视图中的一些元素消失了
    猜你喜欢
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    • 2019-09-05
    • 2011-05-21
    相关资源
    最近更新 更多