В Swift, сброс свойства внутри didSet вызывает другой didSet?
Я проверяю это, и кажется, что если вы измените значение в didSet
, вы не получите еще один звонок didSet
,
var x: Int = 0 {
didSet {
if x == 9 { x = 10 }
}
}
Могу ли я на это положиться? Это где-то задокументировано? Я не вижу этого в документе Swift Programming Language.
3 ответа
Я также думал, что это невозможно (возможно, это не было в Swift 2), но я проверил это и нашел пример, где Apple использует это. (В разделе "Запрос и настройка свойств типа")
struct AudioChannel {
static let thresholdLevel = 10
static var maxInputLevelForAllChannels = 0
var currentLevel: Int = 0 {
didSet {
if currentLevel > AudioChannel.thresholdLevel {
// cap the new audio level to the threshold level
currentLevel = AudioChannel.thresholdLevel
}
if currentLevel > AudioChannel.maxInputLevelForAllChannels {
// store this as the new overall maximum input level
AudioChannel.maxInputLevelForAllChannels = currentLevel
}
}
}
}
И под этим фрагментом кода есть следующее примечание:
В первой из этих двух проверок наблюдатель didSet устанавливает currentLevel в другое значение. Это, однако, не вызывает повторного вызова наблюдателя.
Из Apple Docs (выделение мое):
Точно так же, если вы реализуете наблюдатель didSet, ему передается постоянный параметр, содержащий старое значение свойства. Вы можете назвать параметр или использовать имя параметра по умолчанию oldValue. Если вы назначаете значение свойству в его собственном обозревателе didSet, новое назначенное вами значение заменяет то, которое было только что установлено.
Итак, присвоение значения в didSet официально одобрено и не вызовет бесконечной рекурсии.
Это будет прекрасно работать, но с точки зрения потребителя вашего API это выглядит как довольно плохая идея.
Это не повторяется, как я и предполагал, так что, по крайней мере, это хорошо.
Я могу вспомнить несколько случаев, когда для сеттера было бы приемлемо изменить то, что я устанавливаю. Одним из таких примеров может быть переменная с углом, который автоматически нормализуется [0, 2π]
,