未在集合

时间:2017-09-07 15:26:32

标签: swift computed-properties

在我的应用中,我想让用户在注册时给我一个显示名称,但如果他们不给我一个,我想用他们的名字和最后一个名字创建一个。

这在我看来有点适合计算属性范例,但并不完全符合。我试着在课堂上这样做:

    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(如果是这种情况)?

提前完成。

2 个答案:

答案 0 :(得分:2)

代码崩溃,因为在setter中,赋值self.displayName =调用setter,它调用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不得与属性相关。

答案 1 :(得分:1)

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

在你得到你的时候:

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

}
相关问题