Измените значение, которое задается в переменной 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
пытается его изменить.
Ответы
Ответ 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 }
}
}