SceneKit, overriding the clone() method of SCNNode

I've become used to inheriting SCNNode for my App and therefore adding extra variables/methods to the inherited class.

However, I've encountered a situation where I need to create a clone of the object (e.g., a copy where the geometry, materials etc. are references rather than a freshly instantiated object)
https://developer.apple.com/documentation/scenekit/scnnode/1408046-clone

However, cloning the inherited class does not, of course, clone the extra member variables in the inherited class. So I have attempted to override clone(), but i can't find an example of how this override is meant to be used in inherited classes?

Code Block
class MyNode : SCNNode {
let url: URL
let someStruct: MyStruct
init?(url: url, someStruct: someStruct) {
self.url = url
self.someStruct = someStruct
}
override func clone() -> Self {
/*
No idea what I'm meant to do in here?
How do I 'clone' url and someStruct members here?
Not sure about the following code either.
*/
super.clone()
return self
}
}



Answered by DTS Engineer in 670203022
Hello,

In your snippet where you are overriding clone(), while at compile-time the type reported for super.clone() is SCNNode, at run-time the type will actually be your subclass "MyNode".

So, to override clone, you might do something like this:

Code Block
override func clone() -> Self {
let clone = super.clone() as! Self // At run-time, this should be Self, so this cast is okay.
clone.url = url
clone.someStruct = someStruct
return clone
}


It would also be appreciated if you could file a bug report for the disagreement between the compile-time type and the run-time type using Feedback Assistant.
In fact, this override isn't even giving me the geometry now... I've clearly not used the base clone() correctly

Code Block language
override func clone() -> Self {
super.clone()
return self
}


Accepted Answer
Hello,

In your snippet where you are overriding clone(), while at compile-time the type reported for super.clone() is SCNNode, at run-time the type will actually be your subclass "MyNode".

So, to override clone, you might do something like this:

Code Block
override func clone() -> Self {
let clone = super.clone() as! Self // At run-time, this should be Self, so this cast is okay.
clone.url = url
clone.someStruct = someStruct
return clone
}


It would also be appreciated if you could file a bug report for the disagreement between the compile-time type and the run-time type using Feedback Assistant.
Thank you gchiste, I really appreciate the help. I've created a feedback report as requested.
FB9077227
SceneKit, overriding the clone() method of SCNNode
 
 
Q