【问题标题】:Do I need to call DispatchQueue when presenting a ViewController from other ViewControllers从其他 ViewController 呈现 ViewController 时是否需要调用 DispatchQueue
【发布时间】:2020-09-08 04:06:58
【问题描述】:

我试图通过将 UIActivityViewController 包含在帮助程序类中来在我的应用程序的多个部分中呈现它。以下代码运行良好,我可以从我的应用程序中的任何其他视图控制器调用 showActivityController() 方法,并且 UIActivityViewController 会按预期显示。

我的问题是,我真的需要在DispatchQueue.main.async 中包含代码以显示UIActivityViewController,如下所示?

我在没有它的情况下尝试了它,它工作正常,但我想确保将它留在那里以后不会造成任何问题。

class HelperClass: UIViewController, UIActivityItemSource{
    static let shared = HelperClass()

    func showActivityController(){
        DispatchQueue.main.async {
            let items = [self]
            let activityController = UIActivityViewController(activityItems: items, applicationActivities: nil)
            UIApplication.shared.keyWindow?.rootViewController?.present(activityController, animated: true)
        }
    }

    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return "Return Type"
    }

    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        if activityType == .message{
            return "Text for iMessage"
        }else if activityType == .mail{
            return "Text for Email" 
        }else{
            return "Text for all other apps"
        }
    }
    func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String {
        return "Email Subject"
    }
}

其他视图控制器的使用

HelperClass.shared.showActivityController()

【问题讨论】:

    标签: ios swift uiactivityviewcontroller dispatch-queue


    【解决方案1】:

    仅在主线程中时不需要。所以写DispatchQueue是多余的

    但如果您想从另一个线程进行演示,则必须使用 DispathchQueue 演示 UI

    假设,您正在进行网络调用,并且在网络调用完成后,您必须显示 UI

    在我看来,您应该从方法中删除调度队列。

    func showActivityController(){
             let items = [self]
                let activityController = UIActivityViewController(activityItems: items, applicationActivities: nil)
                UIApplication.shared.keyWindow?.rootViewController?.present(activityController, animated: true)
        }
    

    但是当你必须从其他线程呈现 UI 时,只需调用主线程中的方法

    DispatchQueue.main.async {
        HelperClass.shared.showActivityController()   
    }
    

    【讨论】:

    • @ Ankur Lahiry - 所以,以我的方式调用DispatchQueue 与您建议的调用它的效果不同,它需要从视图控制器中调用介绍它吗? DispatchQueue.main.async { HelperClass.shared.showActivityController() }
    • @fs_tigre 可以说两种情况。首先,您按下一个按钮并显示另一个视图。其次,您按下一个按钮,创建一个 api 调用,并在 api 结束时呈现视图。在第一种情况下,你在主线程上很乖,所以不需要调用 DispatchQueue。在第二种情况下,api调用需要一些时间,但线程执行并没有停止,它还在做其他任务。所以当 API 调用完成时,你会说“嘿,主线程,你现在必须显示一个 viewController,来吧”,所以你通过调用 DispatchQueue 块来做到这一点。
    • 有道理,我只是认为通过像我目前拥有的那样调用它就像从其他视图控制器调用它一样,但我现在明白了,必须从将呈现的控制器调用 DispatchQueue看法。谢谢
    【解决方案2】:

    最好将所有与接口相关的代码保留在主线程上,因此我会将其保留在 DispatchQueue.main.async 中,因为在某些时候您可以从在后台线程上执行的闭包中调用 showActivityController(),从而导致 运行时错误。调用DispatchQueue.main.async 更安全,并且不会产生任何开销,直到您连续调用此方法一百万次。

    【讨论】:

    • 非常感谢您的输入,即使您的声明是正确的,所有接口代码必须保留在主线程中,我认为删除 DispatchQueue 并直接从视图控制器调用它更有意义这将改为呈现 UIActivityController。谢谢
    • @fs_tigre 这完全取决于您,在HelperClassview controller 中使用此块没有功能差异,它只是为您节省了一些输入。最好的问候。
    • 嗯,没关系?如果没关系,如果由于某种原因我在从其他视图控制器调用showActivityController() 时忘记调用DispatchQueue,那么以这种方式保持HelperClass 可能更安全,这不会有问题。有没有办法测试它以确保从HelperClass 调用DispatchQueue 就足够了?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 2020-01-25
    • 1970-01-01
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多