Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

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,662 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...