Подтвердить что ты не робот

Измените значение, которое задается в переменной willSet block

Я пытаюсь сортировать массив, который устанавливается перед его настройкой, но аргумент willSet является неизменным, а sort изменяет значение. Как я могу преодолеть этот предел?

var files:[File]! = [File]() {
    willSet(newFiles) {
        newFiles.sort { (a:File, b:File) -> Bool in
            return a.created_at > b.created_at
        }
    }
}

Чтобы исключить этот вопрос из моего собственного контекста проекта, я сделал это:

class Person {
    var name:String!
    var age:Int!

    init(name:String, age:Int) {
        self.name = name
        self.age = age
    }
}

let scott = Person(name: "Scott", age: 28)
let will = Person(name: "Will", age: 27)
let john = Person(name: "John", age: 32)
let noah = Person(name: "Noah", age: 15)

var sample = [scott,will,john,noah]



var people:[Person] = [Person]() {
    willSet(newPeople) {
        newPeople.sort({ (a:Person, b:Person) -> Bool in
            return a.age > b.age
        })

    }
}

people = sample

people[0]

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

4b9b3361

Ответ 1

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


Как изменить его для использования didSet?
var people:[Person] = [Person]()
{
    didSet
    {
        people.sort({ (a:Person, b:Person) -> Bool in
            return a.age > b.age
        })
    }
}

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

Подробнее о наблюдателях свойств читайте здесь. https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html

Вы также можете написать пользовательский getter и setter, как показано ниже. Но didSet кажется более удобным.

var _people = [Person]()

var people: [Person] {
    get {
        return _people
    }
    set(newPeople) {
        _people = newPeople.sorted({ (a:Person, b:Person) -> Bool in
            return a.age > b.age
        })
    }

}

Ответ 2

Невозможно изменить типы значений (включая массивы), прежде чем они будут установлены внутри willSet. Вам нужно будет вместо этого использовать вычисленное свойство и резервное хранилище:

var _people = [Person]()

var people: [Person] {
    get {
        return _people
    }
    set(newPeople) {
        _people = newPeople.sorted { $0.age > $1.age }
    }
}