【问题标题】:Computed property not computed on set未在集合上计算的计算属性
【发布时间】:2018-02-16 09:56:09
【问题描述】:

在我的应用中,我希望允许用户在注册时给我一个显示名称,但如果他们不给我,我想使用他们的名字和姓氏首字母创建一个。

在我看来,这在某种程度上符合计算属性范式,但并不完全符合。我尝试在课堂上这样做:

    var displayName: String {
    get {
        if (!self.displayName.isEmpty) {
            return self.displayName
        }
        else {
            let index = self.lastName.index((self.lastName.startIndex), offsetBy: 1)

            return self.firstName + " " + self.lastName.substring(to: index)
        }
    }
    set(displayName) {
        self.displayName = displayName
    }
}

但它在几个不同的地方坠毁。这是计算属性的正确情况,还是我应该只创建一个常规属性并检查 displayName.isEmpty 并将其设置为 firstname.lastinitial 如果是这种情况?

提前感谢。

【问题讨论】:

    标签: swift computed-properties


    【解决方案1】:

    代码崩溃是因为在 setter 中赋值 self.displayName = 调用 setter 调用 setter 调用 setter ...这会导致无限循环。计算属性的设置器必须从其他地方计算

    例如,对于具有 getter 和 setter 的计算属性,一个合适的解决方案是将 firstNamelastName 从和到 displayName 映射

    var displayName: String {
        get {
            return firstName.isEmpty ? lastName : firstName + " " + lastName
        }
        set {
            let components = newValue.components(separatedBy: " ")
            if components.count == 2 {
                firstName = components[0]
                lastName = components[1]
            } else {
                firstName = ""
                lastName = newValue
            }
        }
    }
    

    注意:将默认的newValue 重命名为属性的名称是个坏主意,newValue 不能与属性相关。

    【讨论】:

    • "newValue 不能与属性相关"为什么?
    • 谢谢。这是一个有效的解决方案,但不考虑用户提供自己的 displayName。 @Luca 的回答更像是我认为需要做的事情。
    【解决方案2】:

    您的应用因循环问题而崩溃。

    你得到你有:

    if (!self.displayName.isEmpty) {
       return self.displayName
    }
    

    我建议你这样的解决方案:

    class User {
    
        private var compoundName: String
        var displayName: String {
            get {
                guard !self.compoundName.isEmpty else {
                    return self.compoundName
                } 
                if let firstLastNameChar = self.lastName.characters.first {
                     return return "\(self.firstName) \(firstLastNameChar)"
                }
                return self.firstName
            }
            set(displayName) {
                self.compoundName = displayName
            }
        }
    
    }
    

    【讨论】:

    • 谢谢,@Luca。这是我怀疑我必须做的。
    猜你喜欢
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 2018-08-28
    • 2019-04-18
    • 2017-07-22
    相关资源
    最近更新 更多