I'm using SpriteKit in an iOS app, and trying to initialize the camera
property of my SKScene in the overridden didMoveToView
method. If I just initialize it like so:
override func didMoveToView(view: SKView) {
...
self.camera = SKCameraNode()
self.addChild(self.camera!)
}
...it throws the exception unexpectedly found nil while unwrapping an Optional value
at the self.addChild
line, but if I do this:
override func didMoveToView(view: SKView) {
...
let camera = SKCameraNode()
self.camera = camera
self.addChild(self.camera!)
}
...it works fine, no exception. Why are these two ways different? Is there some kind of garbage collection happening? Its not inconvenient to use the second format, that works, but I'm curious what differs that I'm missing.
The camera
property of SKScene
is defined as weak
:
weak public var camera: SKCameraNode?
Therefore, as ARC will deallocate any instance that doesn't have a strong reference to it (Swift uses ARC, not garbage collection) – as soon as you assign SKCameraNode()
to it, it will be deallocated and therefore will be nil
. You then proceed to force unwrap it (which you should always avoid doing), causing the crash.
Your second example works as you have a strong reference to your camera instance through your
let camera = SKCameraNode()
declaration, therefore preventing it from being deallocated while that strong reference to it exists (note that addChild
will also create a strong reference to it).