【发布时间】:2018-08-01 17:34:27
【问题描述】:
我有一个核心数据实体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
}
}
我在UITableViewCell 中显示Person 实例的age。此实例 (person) 的年龄值为 10.0,即person.age.value = 10.0,因此当通过UIStepper 以编程方式将比例更改为scale = 2.0 时,UITableViewCell 显示20.0(即@987654340 @)。
然而,我发现如果我将UIStepper 增加足够多次,最终Person 的Age 类的初始化在tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 方法期间被调用,该方法在给定的IndexPath 处返回Person 的实例。这显然会导致调用Age 类中的init?(coder aDecoder: NSCoder) 方法,从而将scale 属性的值重置为1。
为什么会发生这种情况,请问有没有办法解决这个问题?我希望scale 属性的值始终保持在@987654351 上设置的值@。
感谢您对此事的任何帮助。
编辑
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]
}
【问题讨论】:
-
This obviously causes the init?(coder aDecoder: NSCoder) method within the Age class to be called: Age 是用什么编码器初始化的?我看不出这里的可变形性如何。是关于持续的年龄,如果重新加载一个单元格,规模就会丢失?每次 UIStepper 更改并重新加载/稍后向 Age 提供所需值时,编码器是否应该存储/保留 Age? -
如何获得人员数组?能否提供
cellForRowAtIndexPath:方法的源代码?age属性的初始化可能是由于将您的Person对象变为错误而引起的。进一步访问age属性将通过init?(coder aDecoder: NSCoder)从存储中恢复它。 -
@cocavo 感谢您的帮助。我已经介绍了如何从存储在
Database实体中的一组People中选择person。 -
据我了解,每次访问时都会生成
people数组。这就是您在cellForRowAtIndexPath:方法中获得新创建的Person对象的原因。尝试只生成一次people数组并将其存储为视图控制器的属性。我想它应该对你有帮助。
标签: ios swift uitableview core-data transformable