[英]UITableView “cellForRowAt: indexPath” Occasionally Calling “init?(coder aDecoder: NSCoder)” on Core Data Attribute
I have a core data entity Person
with a transformable attribute age
of type Age
. 我有一个核心数据实体
Person
,其变换属性age
为Age
。
final class Person: NSManagedObject {
@NSManaged public fileprivate(set) var age: Age
}
Age
adopts the NSCoding
protocol and has two variables value
and scale
, but only the value
is saved: 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
}
}
I display the age
of an instance of Person
within a UITableViewCell
. 我在
UITableViewCell
显示Person
实例的age
。 This instance ( person
) has an age value of 10.0, ie person.age.value = 10.0
, such that when the scale is changed programatically to say scale = 2.0
via a UIStepper
, the UITableViewCell
displays 20.0
(ie scale * value
). 此实例(
person
)的年龄值为10.0,即person.age.value = 10.0
,这样当通过UIStepper
以编程方式更改scale = 2.0
以表示scale = 2.0
, UITableViewCell
显示20.0
(即scale * value
)。
However , I'm finding that if I increment the UIStepper
enough times eventually the initialisation of the Age
class for the Person
is called during the tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
method, which returns an instance of Person
at a given IndexPath
. 但是 ,我发现如果我增加
UIStepper
足够的次数,最终会在tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
方法中调用Person
的Age
类的初始化,该方法返回一个实例Person
在给定的IndexPath
。 This obviously causes the init?(coder aDecoder: NSCoder)
method within the Age
class to be called, which resets the value of the scale
property to 1. 这显然会导致调用
Age
类中的init?(coder aDecoder: NSCoder)
方法,这会将scale
属性的值重置为1。
Why does this happen, please, and is there a way fixed this at all? 请问为什么会发生这种情况,是否有办法解决这个问题? I ideally want the value of the
scale
property to always remain what it is set to on the UIStepper
. 理想情况下,我希望
scale
属性的值始终保持在UIStepper
上设置的UIStepper
。
Thanks for any help on this matter. 感谢您对此事的任何帮助。
EDIT 编辑
A given person
at an indexPath
is obtained in the following way: 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]
}
Your people
property is a computed property , which means you get a new people array every time you access it by people[indexPath.item]
. 您的
people
属性是一个计算属性 ,这意味着每次人们访问它时都会获得一个新的人员数组people[indexPath.item]
。 So you are initializing a new Person instance every time you call func person(at:)
, which I guess in tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
. 所以每次调用
func person(at:)
时都要初始化一个新的Person实例,我想在tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
。
Test this by changing the stepper value, and then make the cell disappear from the screen and come back to the same cell. 通过更改步进器值进行测试,然后使单元格从屏幕上消失并返回到同一单元格。 Then the age will have been reset.
然后年龄将被重置。
Just make your people array a stored property like this. 只需让你的人员数组成为这样的存储属性。
private var people: [Person] = Array(database.people).sortedArray(using: Person.defaultSortDescriptors)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.