从绩效明智:类计算属性与存储属性

时间:2015-12-21 22:29:31

标签: ios swift class-design

所以,我有这种情况,var3的值取决于var1var2。基本上,这可以转换成两种形式:

A)使用var3的计算属性

class bla {
    var var1: Int = 0
    var var2: Int = 0
    var var3: Int {
        return var1 * var2
    }
}

B)对var1和var2使用属性观察者的存储属性

class bla {
    var var1: Int = 0 {
        didSet {
            var3 = var1 * var2
        }
    }
    var var2: Int = 0 {
        didSet {
            var3 = var1 * var2
        }
    }
    var var3: Int = 0
}

但是,在我必须处理这个问题的情况下,变量是在UITableViewCell中使用的巨大模型对象的所有部分。在这样的环境中使用,它确实需要尽可能高效,这就是我试图远离使用计算属性的原因。因为据我所知,当Swift得到var3'在 A类实现下的值,它将动态计算其值,而不是像 B类实现那样缓存它。对? (Swift是否以任何方式缓存计算属性的值?)

现在我真的想知道应该采用什么样的最佳方法。事实上,我将其中一些变量迁移到模型对象而不是在单元格内即时计算它们的关键点是从单元格中获取负载并尽可能平滑地滚动,这告诉了使用计算属性使我的努力毫无意义。另一方面,我遇到了其中一个变量依赖于3~4个其他变量的情况,这使得有必要在每个值发生变化时重新计算它,我想这也是无效的。

有什么建议吗?我做错了吗?

1 个答案:

答案 0 :(得分:0)

这是我目前使用的方法,其中需要在某个时刻计算实例属性并缓存以供后续访问:

class AClassWithCachedInstanceVariables {

    private var _var1: Var1Type?

    var var1: Var1Type {
        if let var1 = self._var1 {
            // cache hit
            return var1
        } else {
            // cache miss
            let var1 = self.getVar1()
            self._var1 = var1
            return var1
        }
    }


    private var _var2: Var2Type?

    var var2: Var2Type {
        if let var2 = self._var2 {
            // cache hit
            return var2
        } else {
            // cache miss
            let var2 = self.getVar2()
            self._var2 = var2
            return var2
        }
    }


    /* Extra: let’s say we also want to require var1 and var2
     to be recomputed whenever this other variable is changed */
    var otherVar: OtherVarType? {
        didSet(oldOtherVar) {
            if otherVar != oldOtherVar {
                self._var1 = nil
                self._var2 = nil
            }
        }
    }

    private func getVar1() -> Var1Type {
        // compute stuff...
        return Var1Type()
    }

    private func getVar2() -> Var2Type {
        // compute stuff...
        return Var2Type()
    }
}