Как мне перезаписать установщик сохраненного свойства в Swift?
В Obj-C я могу перезаписать его сеттер, но Swift, похоже, не доволен тем, что геттеры / сеттеры используются для сохраненного свойства.
Скажем, у меня есть Card
класс со свойством под названием rank
. Я не хочу, чтобы клиент давал ему какое-либо недопустимое значение, поэтому в объекте-C я могу перезаписать, setRank
чтобы он выполнял дополнительную проверку. Но willSet
в Swift, похоже, не помогает, потому что newValue
он постоянен и нет смысла назначать, rank
потому что сеттер будет вызываться в цикле.
Ответы:
Хорошо. Читая документацию Apple по Swift, я обнаружил следующее :
Итак, все, что вам нужно сделать, это:
источник
var rankTimesTwo: Int { get { return rank * 2 } }
Вы не можете переопределить
get
/set
для сохраненного свойства, но можете использовать наблюдатели свойствwillSet
/didSet
:Имена параметров по умолчанию предназначены
newValue
дляwillSet
иoldValue
дляdidSet
, или вы можете назвать их сами, как вwillSet(newTotalSteps)
.источник
Card
класс со свойством под названиемrank
. Я не хочу, чтобы клиент давал ему какое-либо значение, поэтому в objective-C я могу перезаписать,setRank
чтобы он выполнил дополнительную проверку. НоwillSet
в Swift, похоже, не помогает, потому чтоnewValue
он постоянен и нет смысла назначать,rank
потому что сеттер будет вызываться в цикле.didSet
для проверкиrank
после того, как он был установлен, и если он не прошел проверку, сбросьте его на что-то еще, напримерoldValue
?get и set предназначены для вычисляемых свойств (у них нет резервного хранилища). (На мой взгляд, ключевое слово var здесь сбивает с толку)
источник
Если вы не хотите использовать didSet, проблема которого заключается в том, что значение свойства временно неверно, вам следует обернуть его вокруг вычисляемого свойства.
Или:
источник
foo
это просто вычисленное выражение_foo
, не позволяйте ключевому слову "var" ввести вас в заблуждение! Это означает, что есть две записи, доступные из частного пространства имен, но это не имеет отношения к защищенному / общедоступному и сохраняет значениеfoo
действительного всегда. По сути, это паттерн «взгляд». Проблема, с которой вы сталкиваетесь при переписывании черезdidSet
, помимо того, что он имеет период недействительности, заключается в том, что существует значительный потенциал для бесконечного цикла, поскольку вы повторно вводитеdidSet
обработчик изнутриdidSet
.Упрощенный пример:
Полный пример
Посмотрите
perimeter
в этом примере.Отрывок из: Apple Inc. «Быстрый язык программирования». iBooks. https://itun.es/us/jEUH0.l
источник
perimeter
это все еще вычисляемое свойство. Как мне перезаписать sideLength, не вводя вычисляемое свойство?get
иset