在Swift中异步地变异集合的惯用方式 [英] Idiomatic Way to Mutate Collection Asynchronously in Swift

查看:46
本文介绍了在Swift中异步地变异集合的惯用方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Swift中异步更改字典/其他集合的惯用的正确方法是什么?

What is the idiomatically correct way to mutate a dictionary/other collection asynchronously in Swift?

在编码时经常会出现以下情况:

The following type of situation often arises while coding:

func loadData(key: String, dict: inout [String: String]) {
    // Load some data. Use DispatchQueue to simulate async request
    DispatchQueue.main.async {
        dict[key] = "loadedData"
    }
}

var dict = [String:String]()

for x in ["a", "b", "c"] {
    loadData(key: x, dict: &dict)
}

在这里,我正在异步加载一些数据,并将其添加到作为参数传入的集合中.

Here, I am loading some data asynchronously and adding it to a collection passed in as a parameter.

但是,由于 inout 的复制语义,该代码无法在Swift中编译.

However, this code does not compile in Swift because of the copy semantics of inout.

我已经想到了两种解决此问题的方法:

I have thought of two workarounds to this problem:

  1. 将字典包装在一个类中,然后将该类传递给函数.然后,我可以对类进行突变,因为它不是值类型.
  2. 使用不安全的指针

惯用的正确方法是哪种?

Which is the idiomatically correct way to do this?

我看到在这个问题中对此主题进行了一些讨论:异步回调中的Inout参数无法正常工作.但是,没有一个答案集中在如何真正解决问题上,只是为什么现在的代码不起作用.

I saw that there is some discussion on this topic in this question: Inout parameter in async callback does not work as expected. However, none of the answers focused on how to actually solve the problem, only why the code as it is now doesn't work.

推荐答案

此(hack)似乎有效:

This (hack) seems to work:

func loadData(key: String, applyChanges: @escaping ((inout [String: String]) -> Void) -> Void) {
    DispatchQueue.main.async {
        applyChanges { dict in
            dict[key] = "loadedData"
        }
    }
}

...

for x in ["a", "b", "c"] {
    loadData(key: x) { $0(&dict) }
}

虽然不是惯用语...我想说的是,惯用语是异步诱变事物.您始终可以在完成处理程序中将要进行的更改返回给集合.对于字典,这可能是另一本字典,然后您将其与原始字典合并.

Not idiomatic though... I would say the idiomatic thing to do here is to not asynchronously mutate things. You can always return the changes you want to do to a collection in a completion handler. In the case of dictionaries, this could be another dictionary that you then merge with the original.

这篇关于在Swift中异步地变异集合的惯用方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆