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

问题描述

我有一些要从磁盘读取到内存中的数据,这花费了不小的时间。 我希望能够做两件事:

  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,但出现错误消息:

实例成员不能在'ViewController'类型上使用

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

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()

认为实例化一个类具有双重作用:利用惰性属性并在需要时调用它:

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

由于某种不理想的原因,该类将类实例化了约一百次。

解决方法

我建议创建一个将数据加载到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()