【问题标题】:Async methods in swift ViewController delegatesswift ViewController 委托中的异步方法
【发布时间】:2022-11-08 00:45:41
【问题描述】:

我有一个观点(为了这个例子,比如说NSOutlineView)。我为它分配了一个委托并覆盖了一个方法,例如:

func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
    let data = ... some async call to fetch data
    let view = makeView(withData: data)
    return view
}

在从异步源获取数据的情况下,这里使用的最佳模式是什么?

【问题讨论】:

  • 您需要将委托方法本身设置为async,否则您如何在同步方法中进行异步工作?
  • 此处显示的委托方法的签名由 Apple 在 NSOutlineView 规范中提供。我的理解是我不能只添加async,Apple 需要这样做。我在这里错过了什么吗?
  • 如果该方法不在您的控制范围内,那么您确实无法修改其类型签名。正如我之前所说,您不能在具有返回值的同步方法中进行异步调用,该返回值取决于异步方法调用的结果。您需要重新构建代码,以便在调用委托方法时数据已准备好,或者在异步方法返回后修改返回的视图,但仍同步返回视图。

标签: swift async-await delegates viewcontroller


【解决方案1】:

同步数据源方法无法返回从异步方法检索到的数据。

因此,这在一定程度上取决于您为什么必须 await 调用某个 async 方法:

  1. 如果它是真正异步的(例如,您需要从远程 Web 服务获取数据),那么想法是您启动数据的获取,暂时返回一些虚拟/空视图,以及当异步请求完成后,您“重新加载”控件,触发它再次获取数据。

  2. 但是,如果您的数据源数据方法是 async 只是因为您碰巧跨越了参与者边界(例如,您的视图在主要参与者上,您的视图模型在自己的参与者上),答案是重构它,以便被调用的方法在同一个actor上。

    在实践中,当与遗留的UIKitCocoa 数据源委托进行交互时,通常将我们的视图模型指定为@MainActor。这样,我们的视图可以与视图模型管理的数据进行交互,而无需调用async

    为了更准确地回答我们的问题,我们需要更多关于代码 sn-p 的“一些异步调用以获取数据”部分的性质的信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多