С этим простым классом я получаю предупреждение компилятора
Попытка изменить / получить доступ в
x
пределах своего собственного установщика / получателя
и когда я использую это так:
var p: point = Point()
p.x = 12
Я получаю EXC_BAD_ACCESS. Как я могу сделать это без явной поддержки ivars?
class Point {
var x: Int {
set {
x = newValue * 2 //Error
}
get {
return x / 2 //Error
}
}
// ...
}
set
вы хотите использоватьdidSet
. При реализации свойства ведут себя по-разному в Swift, чем Objective-C или другие языкиset
. Смотрите ответ ниже от @jack и примерdidSet
от @cSquirrelОтветы:
Сеттеры и геттеры применяются к
computed properties
; такие свойства не имеют хранилища в экземпляре - значение из получателя предназначено для вычисления из других свойств экземпляра. В вашем случае нетx
назначения.Явно: «Как я могу сделать это без явной поддержки ivars». Вы не можете - вам понадобится что-то для резервного копирования вычисленного свойства. Попробуй это:
В частности, в Swift REPL:
источник
Сеттеры / геттеры в Swift сильно отличаются от ObjC. Свойство становится вычисляемым свойством, что означает, что оно не имеет
_x
вспомогательной переменной, как в ObjC.В приведенном ниже коде решения вы можете видеть, что
xTimesTwo
ничего не хранится, а просто вычисляется результатx
.Смотрите Официальные документы по вычислительным свойствам .
Функциональность, которую вы хотите, также может быть Property Observers .
Что вам нужно это:
Вы можете изменить другие свойства в установщике / получателе, для чего они и предназначены.
источник
didSet
что позволит вам изменить значение сразу после его установки. Ничего не получится, хотя ...x
вернуться к немуoldValue
вdidSet
. Это изменение в поведении очень запутанно, исходя из свойств Objective-C, спасибо!Вы можете настроить установленное значение с помощью свойства обозревателя. Для этого используйте «didSet» вместо «set».
Что касается добытчика ...
источник
x
со значением по умолчанию в этом шаблоне?var x: Int = 0 { didSet { ...
.Чтобы уточнить ответ GoZoner:
Ваша настоящая проблема здесь в том, что вы рекурсивно вызываете свой метод получения.
Как и в приведенном выше комментарии к коду, вы бесконечно вызываете метод получения свойства x, который будет выполняться до тех пор, пока вы не получите код EXC_BAD_ACCESS (вы можете увидеть счетчик в правом нижнем углу игровой среды вашего Xcode).
Рассмотрим пример из документации Swift :
Обратите внимание, что вычисляемое в центре свойство никогда не изменяет и не возвращает себя в объявлении переменной.
источник
get
. Потому что это вызовет другое,get
которое вызовет другое. , , Даже не печатайте это. Потому что для печати также необходимо «получить» значение, прежде чем оно сможет его напечатать!Для переопределения
setter
иgetter
для быстрых переменных используйте приведенный ниже кодНам нужно сохранить значение переменной во временной переменной, поскольку попытка доступа к той же переменной, чей метод getter / setter переопределяется, приведет к бесконечным циклам.
Мы можем вызвать сеттер просто так
Getter будет вызываться при стрельбе ниже заданной строки кода
источник
Вы рекурсивно определяете
x
сx
. Как будто кто-то спрашивает тебя, сколько тебе лет? И вы отвечаете: «Я вдвое старше меня». Что бессмысленно.Вы должны сказать, что я в два раза старше Джона или любой другой переменной, кроме вас самих.
вычисляемые переменные всегда зависят от другой переменной.
Правило большого пальца никогда не получить доступ к самой собственности из внутри - газопоглотителя т.е.
get
. Потому что это вызовет другое,get
которое вызовет другое. , , Даже не печатайте это. Потому что для печати также необходимо «получить» значение, прежде чем оно сможет его напечатать!Так как это даст следующее предупреждение:
Ошибка выглядит примерно так:
В качестве альтернативы вы можете использовать
didSet
. С помощьюdidSet
вы получите значение, которое было установлено ранее и только что установлено. Для получения дополнительной информации см. Этот ответ .источник
Обновление: Swift 4
В приведенном ниже классе сеттер и геттер применяются к переменной
sideLength
Создание объекта
добытчик
сеттер
источник
Попробуйте использовать это:
Это в основном ответ Джека Ву, но разница состоит в том, что в ответе Джека Ву его переменная x
var x: Int
, по моему, моя переменная x, выглядит следующим образом:var x: Int!
поэтому я всего лишь сделал ее необязательным типом.источник
Обновление для Swift 5.1
Начиная с Swift 5.1, теперь вы можете получить свою переменную без использования ключевого слова get . Например:
источник
Сеттеры и геттеры в Swift применяются к вычисляемым свойствам / переменным. Эти свойства / переменные на самом деле не хранятся в памяти, а вычисляются на основе значения хранимых свойств / переменных.
См. Документацию Apple Swift на эту тему: Объявления переменных Swift .
источник
Вот теоретический ответ. Это можно найти здесь
источник