UITableView "cellForRowAt: indexPath" 偶尔调用 "init?(coder aDecoder: NSCoder)" 核心数据属性

UITableView "cellForRowAt: indexPath" Occasionally Calling "init?(coder aDecoder: NSCoder)" on Core Data Attribute

我有一个核心数据实体 Person,其可转换属性 age 类型为 Age

final class Person: NSManagedObject {
    @NSManaged public fileprivate(set) var age: Age
}

Age采用NSCoding协议,有两个变量valuescale,但只保存了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
    }

}

我在 UITableViewCell 中显示 Person 实例的 age。此实例 (person) 的年龄值为 10.0,即 person.age.value = 10.0,因此当通过 UIStepper 以编程方式将比例更改为 scale = 2.0 时,UITableViewCell 显示 20.0(即 scale * value)。

但是,我发现如果我将 UIStepper 增加足够的次数,最终 Age class 的初始化PersontableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 方法期间被调用,returns 在给定的 IndexPathPerson 的一个实例。这显然会导致调用 Age class 中的 init?(coder aDecoder: NSCoder) 方法,从而将 scale 属性 的值重置为 1。

为什么会发生这种情况,有没有办法解决这个问题? 我理想情况下希望 scale 属性 的值是始终保持在 UIStepper.

上的设置

感谢您对此事的任何帮助。

编辑

indexPath 处给定的 person 通过以下方式获得:

private var people: [Person] {
    return Array(database.people).sortedArray(using: Person.defaultSortDescriptors)
}

private func person(at indexPath: IndexPath) -> Person {
    return people[indexPath.item]
}

你的 people 属性 是一个 computed property,这意味着你每次通过 people[indexPath.item] 访问它时都会得到一个新的 people 数组。所以你每次调用 func person(at:) 时都会初始化一个新的 Person 实例,我猜这在 tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell.

通过更改步进值进行测试,然后使单元格从屏幕上消失并返回到同一单元格。那么年龄就已经重置了。

只需像这样将您的人员数组存储 属性。

private var people: [Person] = Array(database.people).sortedArray(using: Person.defaultSortDescriptors)