在我的应用中,我想让用户在注册时给我一个显示名称,但如果他们不给我一个,我想用他们的名字和最后一个名字创建一个。
这在我看来有点适合计算属性范例,但并不完全符合。我试着在课堂上这样做:
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(如果是这种情况)?
提前完成。
答案 0 :(得分:2)
代码崩溃,因为在setter中,赋值self.displayName =
调用setter,它调用setter调用setter ...这会导致无限循环。计算属性的setter必须从其他地方计算。
使用getter和setter计算属性的合适解决方案是将firstName
和lastName
映射到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
}
}
}