计算 属性 未在集合上计算

Computed property not computed on set

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

这在我看来有点符合计算的 属性 范式,但不完全符合。我试图在我的 class:

中这样做
    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?

提前致谢

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

在你得到你有:

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
        }
    }

}

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

计算 getter 和 setter 的 属性 的合适解决方案是将 firstNamelastNamedisplayName 映射到 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不能与属性相关。