Имущество и сеттеры

С помощью этого простого classа я получаю предупреждение компилятора

Попытка изменить / получить доступ к x пределах своего собственного сеттера / получателя

и когда я использую его так:

 var p: point = Point() px = 12 

Я получаю EXC_BAD_ACCESS. Как я могу это сделать без явной поддержки иваров?

 class Point { var x: Int { set { x = newValue * 2 //Error } get { return x / 2 //Error } } // ... } 

Setters и Getters применяются к computed properties ; такие свойства не хранятся в экземпляре – значение из геттера предназначено для вычисления из других свойств экземпляра. В вашем случае нет x для назначения.

Явно: «Как я могу это сделать без явной поддержки иваров». Вы не можете – вам нужно что-то сделать для резервного копирования вычисленного свойства. Попробуй это:

 class Point { private var _x: Int = 0 // _x -> backingX var x: Int { set { _x = 2 * newValue } get { return _x / 2 } } } 

В частности, в Swift REPL:

  15> var pt = Point() pt: Point = { _x = 0 } 16> pt.x = 10 17> pt $R3: Point = { _x = 20 } 18> pt.x $R4: Int = 10 

Сеттеры / геттеры в Swift сильно отличаются от ObjC. Свойство становится вычисленным свойством, которое означает, что он не имеет переменной поддержки, такой как _x как это было бы в ObjC.

В приведенном ниже коде решения вы можете видеть, что xTimesTwo ничего не хранит, а просто вычисляет результат из x .

См. Официальные документы о вычисленных свойствах .

Функциональность, которую вы хотите, также может быть Property Observer .

Что вам нужно:

 var x:Int var xTimesTwo:Int { set { x = newValue / 2 } get { return x * 2 } } 

Вы можете изменить другие свойства в сеттер / получателях, для чего они предназначены.

Вы можете настроить заданное значение, используя свойство observer. Для этого используйте ‘didSet’ вместо ‘set’.

 class Point { var x:Int { didSet { x = x * 2 } } ... 

Что касается геттера …

 class Point { var doubleX: Int { get { return x / 2 } } ... 

Чтобы уточнить ответ Гозонера:

Ваша настоящая проблема заключается в том, что вы рекурсивно называете своего геттера.

 var x:Int { set { x = newValue * 2 // This isn't a problem } get { return x / 2 // Here is your real issue, you are recursively calling // your x property's getter } } 

Как и вышеприведенный комментарий к коду, вы бесконечно вызываете геттер свойства x, который будет продолжать выполняться до тех пор, пока вы не получите код EXC_BAD_ACCESS (вы можете увидеть счетчик в нижнем правом углу игровой площадки Xcode).

Рассмотрим пример из документации Swift :

 struct Point { var x = 0.0, y = 0.0 } struct Size { var width = 0.0, height = 0.0 } struct AlternativeRect { var origin = Point() var size = Size() var center: Point { get { let centerX = origin.x + (size.width / 2) let centerY = origin.y + (size.height / 2) return Point(x: centerX, y: centerY) } set { origin.x = newValue.x - (size.width / 2) origin.y = newValue.y - (size.height / 2) } } } 

Обратите внимание, как вычисляемое центром значение никогда не изменяет или не возвращает себя в объявлении переменной.

Чтобы переопределить setter и getter для быстрых переменных, используйте приведенный ниже код

 var temX : Int? var x: Int?{ set(newX){ temX = newX } get{ return temX } } 

Нам нужно сохранить значение переменной во временной переменной, так как пытаемся получить доступ к той же переменной, чей геттер / сеттер переопределен, приведет к бесконечным циклам.

Мы можем вызвать установщика просто так

 x = 10 

Getter будет вызываться при стрельбе ниже данной строки кода

 var newVar = x 

Вы рекурсивно определяете x с x . Как будто кто-то спрашивает вас, сколько вам лет? И вы отвечаете: «Я вдвое старше своего возраста». Что бессмысленно.

Вы должны сказать, что я вдвое больше возраста Джона или любой другой переменной, кроме вас.

вычисленные переменные всегда зависят от другой переменной.


Правило большого пальца никогда не получает доступ к самому свойству из getter ie get . Потому что это вызвало бы другое get которое вызвало бы другое. , , Даже не печатайте его. Потому что печать также требует «получить» значение, прежде чем он сможет его распечатать!

 struct Person{ var name: String{ get{ print(name) // DON'T do this!!!! return "as" } set{ } } } let p1 = Person() 

Поскольку это даст следующее предупреждение:

Попытка получить доступ к «имени» изнутри собственного получателя.

Ошибка выглядит туманно:

введите описание изображения здесь

В качестве альтернативы вы можете использовать didSet . С помощью didSet вы получите didSet к значению, которое было установлено ранее и только что настроено. Подробнее см. Этот ответ .

Попробуйте использовать это:

 var x:Int! var xTimesTwo:Int { get { return x * 2 } set { x = newValue / 2 } } 

Это в основном ответ Джека Ву, но разница в том, что в ответе Джека Ву его переменная x – это переменная var x: Int , моя моя переменная x выглядит так: var x: Int! , так что все, что я сделал, это сделать его необязательным.

Обновление: Swift 4

В приведенном ниже classе setter и getter применяются к переменной sideLength

 class Triangle: { var sideLength: Double = 0.0 init(sideLength: Double, name: String) { //initializer method self.sideLength = sideLength super.init(name: name) numberOfSides = 3 } var perimeter: Double { get { // getter return 3.0 * sideLength } set { //setter sideLength = newValue / 4.0 } } 

Создание объекта

 var triangle = Triangle(sideLength: 3.9, name: "a triangle") 

добытчик

 print(triangle.perimeter) // invoking getter 

сеттер

 triangle.perimeter = 9.9 // invoking setter 

Сеттеры и геттеры в Swift применяются к вычисленным свойствам / переменным. Эти свойства / переменные фактически не хранятся в памяти, а скорее вычисляются на основе значения хранимых свойств / переменных.

См. Документацию Apple Swift по этому вопросу: Swift Variable Declarations .

Вот теоретический ответ. Это можно найти здесь

Свойство {get set} не может быть постоянным сохраненным свойством. Это должно быть вычисленное свойство, и как get, так и set должны быть реализованы.

  • Получить имя свойства как строку
  • Как читать файл свойств в веб-приложении?
  • Разница между свойством и полем в C # 3.0+
  • Использование @property против геттеров и сеттеров
  • В чем разница между свойством Property и Dependency Property
  • Как настроить log4j с файлом свойств
  • `def` vs` val` vs `lazy val` в Scala
  • Обратный вызов, когда свойство зависимостей получает изменение xaml
  • Резервный список
  • Ошибка в classе Swift: свойство не инициализировано при вызове super.init
  • Как получить список свойств classа?
  • Давайте будем гением компьютера.