UITableView "cellForRowAt: indexPath" Иногда вызывается "init?(Кодер aDecoder: NSCoder)" на базовом атрибуте данных
У меня есть основной объект данных Person
с трансформируемым атрибутом age
типа Age
,
final class Person: NSManagedObject {
@NSManaged public fileprivate(set) var age: Age
}
Age
принимает NSCoding
протокол и имеет две переменные value
а также scale
, но только value
сохраняется:
class Age: NSObject, NSCoding {
@objc public var value: Double
public var scale = 1.0
override public var description: String {
return "\(scale * value)"
}
func encode(with aCoder: NSCoder) {
aCoder.encode(value, forKey: #keyPath(value))
}
public convenience required init?(coder aDecoder: NSCoder) {
self.init(value: aDecoder.decodeDouble(forKey: #keyPath(value)))
}
init(value: Double) {
self.value = value
}
}
Я отображаю age
экземпляра Person
в пределах UITableViewCell
, Этот экземпляр (person
) имеет возрастное значение 10,0, т.е. person.age.value = 10.0
так, что когда масштаб изменяется программно, сказать scale = 2.0
через UIStepper
, UITableViewCell
дисплеи 20.0
(т.е. scale * value
).
Тем не менее, я считаю, что если я увеличу UIStepper
достаточно раз в конце концов инициализация Age
класс для Person
называется во время tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
метод, который возвращает экземпляр Person
в данный момент IndexPath
, Это, очевидно, вызывает init?(coder aDecoder: NSCoder)
метод в пределах Age
вызываемый класс, который сбрасывает значение scale
собственность на 1.
Почему это происходит, пожалуйста, и есть ли способ исправить это вообще? Я в идеале хочу значение scale
свойство всегда оставаться тем, что установлено на UIStepper
,
Спасибо за любую помощь в этом вопросе.
РЕДАКТИРОВАТЬ
Данный person
загар indexPath
получается следующим образом:
private var people: [Person] {
return Array(database.people).sortedArray(using: Person.defaultSortDescriptors)
}
private func person(at indexPath: IndexPath) -> Person {
return people[indexPath.item]
}
1 ответ
Ваш people
свойство является вычисляемым свойством, что означает, что вы получаете новый массив людей каждый раз, когда обращаетесь к нему people[indexPath.item]
, Таким образом, вы инициализируете новый экземпляр Person каждый раз, когда звоните func person(at:)
Я думаю, что в tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
,
Проверьте это, изменив значение шага, а затем заставьте ячейку исчезнуть с экрана и вернуться к той же ячейке. Тогда возраст будет сброшен.
Просто сделайте так, чтобы ваши люди хранили массив хранимых свойств следующим образом.
private var people: [Person] = Array(database.people).sortedArray(using: Person.defaultSortDescriptors)