Search code examples
swiftoption-typeforced-unwrapping

Unwrapping optionals in Apple's game code project template


In the small sample of Apple's code which is created when you make a new game project in Xcode, the GameScene has several functions which use an unwrapping pattern I've not come across, & I fail to see the point of it -

if let n = self.spinnyNode?.copy() as! SKShapeNode? { ...code... }

Two questions - (1) is this dangerous, & (2) why not use the more common pattern -

if let n = self.spinnyNode?.copy() as? SKShapeNode { ...code... }

I can find nothing relating to this on SO or Google...


Solution

  • Lets break down the original line of code:

    if let n = self.spinnyNode?.copy() as! SKShapeNode? { ...code... }
    
    1. self.spinnyNode is declared as an SKShapeNode?. In other words, it's an optional SKShapeNode.
    2. SKShapeNode inherits from NSObject which provides the copy method. The copy method is declared to return Any.
    3. self.spinnyNode?.copy() will return an Any? with a value of nil if self.spinnyNode is nil or it will return a non-nil Any? if it's not.

    So the compiler thinks that self.spinnyNode?.copy() will return an Any?. But we know it will really return a SKShapeNode?. Since we know what it will really be we can safely use as!. And since we know it will return a SKShapeNode?, we use as! SKShapeNode?.

    At this point we could have:

    let n = self.spinnyNode?.copy() as! SKShapeNode?
    

    where n will be a SKShapeNode?.

    Since we now want to safely unwrap the result, we add the if in front of the let:

    if let n = self.spinnyNode?.copy() as! SKShapeNode? { ...code... }
    

    and inside the block we know that n is a non-nil SKShapeNode.

    With all of that, let's answer your questions:

    1. Is this dangerous? No, not in this case since we know for sure that self.spinnyNode?.copy() will always result in a SKShapeNode? we can safely use as! to cast it to SKShapeNode?.
    2. Why not use the more common as? SKShapeNode pattern? We could but that pattern is used when you don't know for sure that the result is actually a SKShapeNode.