如何解决如何观察继承对象属性的变化并存储以前的值?
设置:
我正在继承 SKSpriteNode()
以创建一个名为 SubNode()
的自定义子类。
SKSPriteNode() 类有一个名为 physicsBody
的属性,它存储一个 SKPhysicsBody()
对象。 SKPhysicsBody
有一个名为“速度”的属性,它是一个 CGVector()
目标:
在我的子类中,我想要一个始终保留前一个 CGVector()
的变量。例如,只要我调用 subNode.physicsBody?.veLocity = CGVector(dx: 10,dy: 10)
。 subNode.prevIoUsveLocity
应设置为之前的 subNode.physicsBody?.veLocity
值。
问题
如果 veLocity
只是超类的继承属性,我可以只 override
该属性并附加一个 didSet
观察者。但是由于 veLocity
是 SKPhysicsBody()
的属性,并且 SKPhysicsBody()
对象在其属性之一发生变化时不会发生变化,因此 didSet
不会被触发,我无法听听它的变化。
如果我的解释不清楚,请要求更多说明。
我的子类:
class SubNode: SKSpriteNode {
var prevIoUsveLocity: CGVector = .zero
// This doesn't get triggered because the physiceBody object doesn't change when one of its properties changes.
override var physicsBody: SKPhysicsBody? {
didSet {
prevIoUsveLocity = oldValue?.veLocity
}
}
// If veLocity would be a property of the superclass,this would trigger.
override var veLocity: CGVector {
didSet {
prevIoUsveLocity = oldValue
}
}
}
从 SubNode() 子类创建对象子节点,设置物理体,然后设置速度"
let subNode = SubNode()
subNode.physicsBody = SKPhysicsBody()
subNode.physicsBody?.veLocity = CGVector(dx: 10,dy: 10)
subNode.physicsBody?.veLocity = CGVector(dx: 0,dy: 0)
//should be true: subnode.prevIoUsveLocity == CGVector(dx: 10,dy: 10)
解决方法
这只是部分答案!只是试图找到问题的解决方案。
我试图以某种方式找到解决方法。我注意到只要对象的属性发生变化,对象的 getter 就会被触发。我创建了以下操场文件,它似乎有效。一旦我更改了对象的文本,以前的名称就会存储在另一个变量中。但从我的测试来看,这似乎有效。我不确定我的逻辑是否正确,或者我是否遗漏了什么,实现应该更简单的东西也可能有点太多了。
下面我为我的子类添加了代码,并且到目前为止我可以测试它确实有效。但是,我希望您能提供一些反馈,了解此解决方案可能存在的缺陷。
import UIKit
class ObjectClass {
var name: String = "Initial Name"
}
class SuperClass {
var object: ObjectClass?
}
class SubClass: SuperClass {
var _oldObjectName: [String?] = [nil]
var oldObjectName: String? {
_ = object?.name
return _oldObjectName.first ?? nil
}
override var object: ObjectClass? {
get {
// Is also being called before the object has been written to.
if !_oldObjectName.contains(super.object?.name) {
_oldObjectName.append(super.object?.name)
_oldObjectName = _oldObjectName.suffix(2)
}
return super.object
}
set {
super.object = newValue
}
}
}
let subClass = SubClass()
subClass.object = ObjectClass()
对我的子类使用上述解决方案:
class SubNode: SKSpriteNode {
private var _previousVelocity: [CGVector?] = []
var previousVelocity: CGVector {
_ = physicsBody?.velocity
return (_previousVelocity.first ?? CGVector.zero)!
}
override var physicsBody: SKPhysicsBody? {
get {
if !_previousVelocity.contains(super.physicsBody?.velocity) {
_previousVelocity.append(super.physicsBody?.velocity)
_previousVelocity = _previousVelocity.suffix(2)
}
return super.physicsBody
}
set {
super.physicsBody = newValue
}
}
}
从我最初的测试来看,到目前为止这似乎有效:
let subNode = SubNode()
subNode.physicsBody = SKPhysicsBody()
subNode.physicsBody?.velocity = CGVector(dx: 10,dy: 10)
subNode.physicsBody?.velocity = CGVector(dx: 0,dy: 0)
//true: subnode.previousVelocity == CGVector(dx: 10,dy: 10)
更新:
我发现这个解决方案的一个问题是,当 ObjectClass() 中的对象首先创建为自己的变量,然后直接通过变量更改时,子类的 getter 将不会被触发,直到通过子类。这对我来说不是问题,但绝对不理想。
let subClass = SubClass()
let object = ObjectClass()
subClass.object = object
// This won't trigger the getter obviously since the subclass is not accessed.
object.name = "New Name"
object.name = "Another Name"
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。