斯威夫特:镜子(反映:自我)太慢了?

时间:2016-07-22 17:14:49

标签: ios swift mirroring

我正在尝试用我的类的属性创建一本字典。

class SomeClass() {
    var someString = "Hello, stackoverflow"
    var someInt = 42 // The answer to life, the universe and everything
    var someBool = true

    func objectToDict() -> [String: String] {
        var dict = [String: String]()
        let reflection = Mirror(reflecting: self)
        for child in reflection.children {
            if let key = child.label {
            dict[key] = child.value as? AnyObject
        }
        return dict
    }
}

objectToDict()非常慢。有没有办法加快速度,或者可能是另一种将属性值添加到字典中的方法?

2 个答案:

答案 0 :(得分:2)

我不同意大多数其他用户。使用反射会减少代码,这意味着开发,维护和测试产品的时间更短。使用像EVReflection这样写得很好的库,你不需要太担心幕后的事情。

但是,如果性能成为一个问题,请 NOT 使用基于反射的方法。我说这在我的前端开发中从来都不是问题,特别是在iOS中,但在后端开发中不容忽视。

为了看它有多慢,我在Xcode中运行了一些测试。我会写一篇关于它的博客,但一般来说,获取Mirror并不是最糟糕的部分(加上它可能会在内存中捕获属性列表),所以用objc运行时替换它不会改变这种情况太多了。另一方面,setValue(_, forKey)出乎意料地缓慢。考虑到在现实生活中你还需要执行检查dynamicType等任务,使用动态方法肯定会使它慢100倍,这对服务器开发来说是不可接受的。

- Looping 1,000,000 times for a class with 1 `Int` property
  - Getting mirror: 1.52
  - Looping throw mirror and set `child.value`: 3.3
  - Looping throw mirror and set `42`: 3.27
  - Setting value `42`: 0.05

同样,对于iOS,我将继续使用它来节省我的时间。希望最终客户不会关心它是0.005秒还是0.0005秒。

答案 1 :(得分:0)

不仅速度慢,而且也不是一个好主意:镜像仅用于调试内省。你应该自己构建字典。这样可以确保您可以灵活地以正确的方式存储所有数据,还可以将Swift属性名称与您生成的字典中的键解耦。

class SomeClass {
    var someString = "Hello, stackoverflow"
    var someInt = 42 // The answer to life, the universe and everything
    var someBool = true

    func objectToDict() -> [String: AnyObject] {
        return ["someString": someString, "someInt": someInt, "someBool": someBool]
    }
}