Swift: Avoiding double-wrapped optionals with conditional downcasting
27th February, 2015 —
Yesterday, I took the plunge and updated Heartbeat to Xcode 6.3 Beta 2. It was actually not a painful process with the automatic migration tool shouldering the brunt of the work for me.
One thing I did notice in my code, however, was a double-wrapped optional where I was trying to access the layer of the content view of a window.
In my original code, I had:
Swift: if let layer = self.window?.contentView.layer? { //…
While that works in the release build, Swift 1.2 in Xcode 6.3 Beta 2 was having none of it.
My initial, naïve refactoring gave me this:
Swift: if let window = self.window, doubleWrappedOptionalWTF = window.contentView.layer, layer = doubleWrappedOptionalWTF { //…
So, to understand why I was getting a double-wrapped optional (CALayer??
), I wrote out the code in longhand:
Swift: let window:NSWindow? = self.window
if let window = window
{
let contentView:NSView? = window.contentView as? NSView
if let contentView = contentView
{
let layer:CALayer? = contentView.layer
if let layer = layer
{
// Do something with the layer…
}
}
}
Ah, well now it’s clear: the “double-wrapping” is because I wasn’t casting contentView
, which returns AnyObject
.
So, let’s apply that back to the one-liner:
Swift: if let window = self.window, contentView = window.contentView as? NSView, layer = contentView.layer { //…
Much nicer.
But I can’t really call it beautiful.