如何从另一个视图重新初始化一个惰性 属性?

How to re-initialize a lazy property from another view?

我有一些数据要从磁盘读入内存,这需要花费大量时间。 我希望能够做两件事:

  1. 我不会在每次加载视图时读取数据。
  2. 我希望能够从另一个视图调用它。
lazy var data: [String: String] = {
    guard let data = readFromDisk() else { return [:] }
    return processData(data: data)
}()

以上代码只在第一次加载视图时初始化一次,这非常适合消除不必要的计算。问题是我还希望能够在需要时从另一个视图触发它。

我尝试触发重新初始化:

func getData() {
    guard let data = readFromDisk() else { return [:] }
    data = processData(data: data)
}

并从另一个视图调用它:

let vc = ViewController()
vc.getData()

但是,不起作用。 我试着看看我是否可以使用 static,因为它也是 lazy,但我收到一条错误消息:

Instance member cannot be used on type 'ViewController'

最后,我尝试创建一个单独的 class:

class DataImporter {
    var data: [String: String] {
        guard let data = readFromDisk() else { return [:] }
        return processData(data: data)
    }
    
    func readFromDisk() -> [String: String] {}
    func processData(data: [String: String]) -> [String: String] {}
}

并且 ViewController 中有懒惰的 属性:

lazy var importer = DataImporter()

认为实例化一个 class 实现了利用惰性 属性 并在需要时调用它的双重效果:

let vc = ViewController()
vc.importer = DataImporter()

由于某些不理想的原因,这实例化了 class 大约一百次。

我建议创建一个将数据加载到 data 的函数,然后当您需要重新加载 data 时,只需重新分配它即可。

class DataStore {
    lazy var data: [String: String] = loadData()

    func readFromDisk() -> Data? {...}

    func processData(data: Data) -> [String:String] { ... }

    func loadData() -> [String:String] {
        guard let data = readFromDisk() else { return [:] }
        return processData(data: data)
    }
}

let store = DataStore()
let data = store.data // only loaded here
store.data = store.loadData() // reloads the data

如果不想暴露loadData函数,也可以单独创建一个reloadData函数。

class DataStore {
    ...
    func reloadData() {
        data = loadData()
    }
}

然后不执行 store.data = store.loadData(),只需调用 store.reloadData()