Вычисляемое свойство не вычисляется на множестве

В моем приложении я хочу разрешить пользователю давать мне отображаемое имя при регистрации, но если они не дают мне его, я хочу создать его, используя свое имя и фамилию.

Мне показалось, что это в некоторой степени соответствует парадигме вычисляемых свойств, но не совсем. Я пытался сделать это в моем классе:

    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 ответа

Решение

Ваше приложение вылетает из-за проблемы с циклом.

На вашем счету у вас есть:

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

}

Код падает, потому что в сеттере присваивание self.displayName = вызывает сеттер, который вызывает сеттер, который вызывает сеттер... который вызывает бесконечный цикл. Установщик вычисляемого свойства должен быть вычислен откуда-то еще.

Подходящим решением для вычисляемого свойства с помощью метода get и set является сопоставление 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 не должны быть связаны с собственностью.

Другие вопросы по тегам