Быстрое программирование: getter/setter в сохраненной собственности - программирование
Подтвердить что ты не робот

Быстрое программирование: getter/setter в сохраненной собственности

Как перезаписать установщик хранимого свойства в Swift?

В Obj-C я могу перезаписать свой сеттер, но Swift, похоже, не очень рад, что getter/setters используются для сохраненного свойства.

Скажем, у меня есть класс Card со свойством rank. Я не хочу, чтобы клиент дал ему какое-либо недопустимое значение, поэтому в objective-C я могу перезаписать setRank, чтобы он выполнял дополнительную проверку. Но willSet в Swift, похоже, не помогает, потому что newValue является константой, и нет смысла назначать rank, потому что setter будет вызываться в цикле.

4b9b3361

Ответ 1

Ok. Чтение документации на яблоки Swift я нашел this:

Если вы присваиваете значение свойству в своем собственном наблюдателе, новое значение, которое вы назначили, заменит тот, который был только что установлен.

Итак, все, что вам нужно сделать, это следующее:

var rank: Int = 0 {
    didSet {
        // Say 1000 is not good for you and 999 is the maximum you want to be stored there
        if rank >= 1000  {
            rank = 999
        }
    }
}

Ответ 2

Вы не можете переопределить get/set для сохраненного свойства, но вы можете использовать наблюдатели свойств willSet/didSet:

var totalSteps: Int = 0 {
    willSet(newTotalSteps) {
        println("About to set totalSteps to \(newTotalSteps)")
    }
    didSet {
        if totalSteps > oldValue  {
            println("Added \(totalSteps - oldValue) steps")
        }
    }
}

Имена параметров по умолчанию newValue для willSet и oldValue для didSet, или вы можете назвать их самостоятельно, как в willSet(newTotalSteps).

Ответ 3

get и set предназначены для вычисляемых свойств (у них нет резервного хранилища). (На мой взгляд, ключевое слово "var" здесь запутывает)

  • willSet и didSet вызывают для переменной экземпляра (Use doSet для переопределения любых изменений)
  • set и get являются чисто рассчитанными свойствами

Ответ 4

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

private var _foo:Int = 0
var foo:Int {
    get {
        return _foo
    }
    set {
        if(newValue > 999) {
            _foo = 999
        } else {
            _foo = newValue
        }
    }
}

Или:

private var _foo:Int = 0
var foo:Int {
    get {
        return _foo
    }
    set {
        guard newValue <= 999 else {
            _foo = 999
            return
        }
        _foo = newValue
    }
}

Ответ 5

Упрощенный пример:

class Shape {
    var sideLength: Double {
    get {
        return self.sideLength
    }
    set {
        // Implement the setter here.
        self.sideLength = newValue
    }
    }
}

Полный пример

Проверьте perimeter в этом примере.

Отрывок из: Apple Inc. "Быстрый язык программирования". интерактивные книги. https://itun.es/us/jEUH0.l

class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0

    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }

    var perimeter: Double {
    get {
        return 3.0 * sideLength
    }
    set {
        sideLength = newValue / 3.0
    }
    }

    override func simpleDescription() -> String {
        return "An equilateral triagle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
triangle.perimeter
triangle.perimeter = 9.9
triangle.sideLength"