【问题标题】:Very slow presentation of the UIAlertControllerUIAlertController 的呈现速度非常慢
【发布时间】:2017-02-23 13:57:40
【问题描述】:

最近让我印象深刻的一件事是 UIAlertController 在其中呈现大量元素时速度有多慢。

我的 for 循环迭代了 400 多个元素。我查了一下,循环只需要几分之一秒,但UIAlertController 的呈现需要超过 16 秒!!

我附上 Time Profiler 输出以支持我所写的内容。 问题是 - 有什么方法可以提高这个组件的速度,或者有没有 UIAlertController 的替代品(自定义库),这在性能方面更好?

DispatchQueue.global(qos: .userInitiated).async {

    for item in items {
      let button = UIAlertAction(title: item.title, style: .default, handler: { (alertAction) in
            //  alert action
        })
        menuValueSelectionController.addAction(button)
    }


    DispatchQueue.main.async {
        if let popoverController = menuValueSelectionController.popoverPresentationController {
            popoverController.sourceView = sender
            popoverController.sourceRect = sender.bounds
        }

        menuValueSelectionController.view.layoutIfNeeded()
        self.present(menuValueSelectionController, animated: true, completion: nil)
    }
}

【问题讨论】:

    标签: ios swift swift3 uialertcontroller


    【解决方案1】:

    我怀疑UIAlertController.addAction() 不是线程安全的。 UIAlertAction 初始化程序可能也不是。

    从后台调用非线程安全的 UIKit 方法是导致 UI 更改生效之前长时间暂停的常见原因。我建议摆脱 DispatchQueue.global().async 包装器。我打赌延迟会大幅下降。

    也就是说,400 个警报操作似乎太多了,无法尝试放入警报控制器。您可能需要寻找其他方法。

    【讨论】:

    • 我检查过了,看来您可以在后台安全地使用UIAlertController.addAction()。将它包装在 DispatchQueue.global().async 中的整个想法来自于 UIAlertController 的非常缓慢的呈现时间:) 采用另一种方法绝对是正确的 - 文档似乎缺少此信息,但应该避免使用 UIAlertController 时处理大量数据。
    • @DuncanC 刚刚在主线程上尝试了相同的代码,400 个动作花了 19 秒。
    • 所以我猜你需要创建一个自定义的模态视图控制器,其中包含一个表格视图。用于处理大量单元格的表格视图。
    • @Michael 以及必须使用它的人怎么办。如果我看到这样的 AlertController,我决定将其从我的设备中删除。我认为,这永远不会发生,Apple 的东西会更早地拒绝它。我很抱歉这么说,但遵循 Apple 规定的 UI 设计建议似乎是个好主意。
    • @user3441734 我完全同意。这种观点早已不复存在。不幸的是,文档似乎缺少有关可能导致此处描述的性能问题的任何限制的信息。
    【解决方案2】:

    看起来UIAlertController 不是为如此大量的操作而设计的。我猜它里面不是UITableView,所以UIAlertController必须一次布置所有这些按钮,这需要很多时间。

    我建议在内部实现带有UITableView 的自定义UITableViewControllerUIViewController 控制器,并以模态方式呈现它而不是UIAlertController

    编辑

    刚刚用 UI 调试器检查了我的假设并意识到我错了。里面确实是UITableView

    【讨论】:

    • 是的,UIAlertController 似乎只是一个 UIScrollView。该引用声称它继承自UIViewControllerdeveloper.apple.com/reference/uikit/uialertcontroller 但对实现细节知之甚少。
    • @Michael 顺便问一下,是actionSheet 还是alert
    • alexburtnik preferredStyle 设置为 actionSheet。对不起,我应该在一开始就提到它。
    • @Michael Hm,它是一个UITableView,每个单元格都有一个标签,你可以看到
    • Alex,你是对的,谢谢你检查。那么性能缓慢的原因仍然未知。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 2016-10-10
    • 2012-11-05
    • 2016-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多