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

标签 ios swift uitableview core-data transformable

我有一个核心数据实体Person具有可变形属性 age类型 Age .

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

Age采用NSCoding协议(protocol)并有两个变量 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
    }

}

我显示 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 上的设置.

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

编辑

给定personindexPath获取方式如下:

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.

通过更改步进器值对此进行测试,然后使单元格从屏幕上消失并返回到同一单元格。然后年龄将被重置。

只需让您的 people 数组成为这样的存储属性即可。

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

关于ios - UITableView "cellForRowAt: indexPath"偶尔在核心数据属性上调用 "init?(coder aDecoder: NSCoder)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51639176/

相关文章:

ios - 为什么 iOS Container 不再取代 work?

ios - ios如何更改ListView的背景颜色

swift - 用手指手势移动 Sprite

iphone - 单个 UIWebView 上的两个网页

ios - 将当前的 UITableViewCell 滑动传递给父 UITableView

ios - swift 将从@escaping 接收到的值分配给另一个类中的实例变量

iphone - 如何使用 UIImageView 和 UILabel 创建 UIBarButtonItem

android - 在本地网络中推送通知

ios - 标记帖子时从 firebase 中删除一个 child

ios - Swift Json 数据解析(无需数组)