Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS Build a Playlist Browser with Swift Building the Music Library and Playlist Models Passing the Playlist Object

Kevin Murphy
Kevin Murphy
24,380 Points

Not clear on when to force unwrap to access a dictionary value (optionals)

Can someone please explain why the (!) operator is essential in this syntax

 buttonPressLabel.text = playlist!.title

and why isn't a (!) operator needed on title as well? e.g.

buttonPressLabel.text = playlist!.title!

Thanks

1 Answer

Chris Shaw
Chris Shaw
26,676 Points

Hi Kevin,

The unwrap symbol or bang as it's known isn't required for title because it's already an unwrapped object, you can see this for yourself if you open up the Playlist.swift file. In the init function of the struct, the value of playlistDictionary["title"] gets downcast to a String and unwrapped as objects without a previously declared type automatically inherit the type AnyObject?.

In the case of PlaylistDetailViewController which is where your question resides, we only need to unwrap playlist because it's declared with the type Playlist? meaning it could be nil or an instance of Playlist but Swift doesn't infer the value which is why we need to test and unwrap it manually.

Hope that helps.

Kevin Murphy
Kevin Murphy
24,380 Points

Hi Chris,

That was how I roughly understood it and now since reading your explanation, fully understand it. However, the root of my confusion lies in that when I was experimenting in the playground and also by adding a println() statement for the value of title, the console returns Optional("Rise and Shine").

Yet when the app is run, the PlaylistDetailViewController displays the title as "Rise and Shine" without error.

So I'm still confused as to why the console shows the value for title as optional despite unwrapping during the downcast. And why if it's in fact an optional there is no error when pressing the button to display the title?

override func viewDidLoad() {
        super.viewDidLoad()
        println(playlist!.title)
        if playlist != nil {
            buttonPressLabel.text = playlist!.title
            println(playlist!.title)
            println(buttonPressLabel.text)
        }

    }

(All three of the above println() statements produce Optional("Rise and Shine") as output to the console)

Thanks for your help

Chris, does this mean that properties of type optionals are no longer optionals if they are set at initialisation?? That makes absolutely no sense to me - if it is declared optional, then it is always an optional even though you set it with an unwrapped value, no??? Also, I would argue that it makes no sense to declare a property optional, if you force unwrap it at initialisation, and never look back (check for nil everywhere else)...

I know there have been a few syntactic changes to swift since it was first introduced - but to be honest, I feel like the speaker is not 100% sure of how and when to use this feature of swift...

Btw.

buttonPressLabel.text = playlist?.title

is just as effective as

if playlist != nil {
  buttonPressLabel.text = playlist!.title
}

That's the beauty of it, and it just adds to the confusion that the speaker is unaware of this...

And Kevin, the reason your println statements all reflect an optional value, is that you are unwrapping the playlist, not the title... The title is still optional. The reason this works with the button label, though, is that the text property on a UILabel is also an optional - so it is quite allowed to set a labels text property to nil - and hence you don't have to unwrap it - like in my example above...