Re: Error unwrapping an optional which isn't an optional
Re: Error unwrapping an optional which isn't an optional
- Subject: Re: Error unwrapping an optional which isn't an optional
- From: Quincey Morris <email@hidden>
- Date: Mon, 21 Sep 2015 12:42:22 -0700
- Feedback-id: 167118m:167118agrif8a:167118sGTcK1ZBZ7:SMTPCORP
On Sep 21, 2015, at 11:01 , Alex Hall <email@hidden> wrote:
>
> I'm setting up a binding using an NSController, which I want to connect the currently selected row in a table to the values of some UI controls. Put another way, whenever the table's selected row changes, the binding should cause some controls to display new information pulled from the row.
Several things about this:
1.
> return currentTab.tweetsList[tweetsTable.selectedRow] //Xcode points to this line as the problem
Sometimes, this sort of thing is just a trivial error because Swift inferred an optional type and you weren’t expecting it. You can solve this by temporarily writing out the code with the types you expect, approximately like this:
let selectedRow: Int = tweetsTable.selectedRow
let tweetsList: [Tweet] = currentTab.tweetsList
let result: Tweet = tweetsList [selectedRow]
Or, it may be something subtler where the SDK has told Swift that an object can’t be nil, but it really can (at run time, because this is Obj-C underneath). This would likely be regarded as a bug in the SDK.
2.
> return currentTab.tweetsList[tweetsTable.selectedRow] //Xcode points to this line as the problem
This is a dangerous line of code, because (if tweetsTable is a table view) tweetsTable.selectedRow can validly be -1, and that’s gonna crash your app.
3. In spite of all the things I’ve said in the recent past, this is one of the situations where you *should* bind the row-specific controls to a NSArrayController’s “selection” property.
That’s because one of the useful bindings behaviors is dealing with situations where you want to show something different for no-selection, single-selection and multiple-selection cases. There are bindings options to disable controls when there isn’t a single selected element, and bindings options to customize placeholder text, too (4 different placeholders, of which you’re likely to want to use just the no-selection and multiple-selection cases).
4.
> dynamic var currentTweet:Tweet? {
> get {
> …
> }
> }
If you have only a getter, there’s no need for the ‘get’ keyword and the unnecessary extra level of braces. All you need is a ‘return’ at the top level of the property. One of the banner features of Swift (for the recovering Obj-C programmer) is that you don’t have to write out syntax that compiler already knows must be there, or that it can reasonably assume. I sympathize with developers whose sense of consistency is offended by this, but OTOH I’ll have finished writing my property before you’ve finished lining up your braces, and my source files will be half the size or yours. ;)
5.
> if let tempTweet=currentTweet, tempID = tempTweet.idAsString {
> return tempID
> }
> return nil
I strongly commend the advantages of ‘guard’ for this sort of thing:
guard let tempTweet=currentTweet, tempID = tempTweet.idAsString else { return nil }
return tempID
This makes it clear that the nil return is exceptional (relative to the name of the property, even if it’s not really an error return), and avoids burying the important answer inside yet more braces.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden