• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Instantiate NSString from NSURL in Swift
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Instantiate NSString from NSURL in Swift


  • Subject: Re: Instantiate NSString from NSURL in Swift
  • From: Fritz Anderson <email@hidden>
  • Date: Mon, 23 Feb 2015 13:52:53 -0600

On 23 Feb 2015, at 8:18 AM, Juanjo Conti <email@hidden> wrote:
>
> I'm translating some code from Objective-C to Swift and in the middle of
> that, i found this problem.
>
> theUrl is an instance of NSURL
>
> theUrl.host?.lowercaseString
>
> compiles ok.
>
> But
>
> NSString(string: theUrl.host?.lowercaseString)
> don't. It says "Value of optional type 'String?' no unwrapped; did you mean
> to use '!' or '?'?
>
> If I click to add the fix, then it complains again and suggest to delete
> the '!' :)

This is written in haste, and few people are experts…

    theURL.host  may yield nil (host is declared String!, implicitly unwrapped, but optional).

    theURL.host?.lowercaseString  will short-circuit and be evaluated as nil if .host is nil.

    anyString.lowercaseString   may also yield nil; the var is declared String!.

    anyString.lowercaseString!   attempts to unwrap a String that the compiler has implicitly unwrapped already.

Therefore, because of the short-circuit “?”, the expression theUrl.host?.lowercaseString is of type String?, which may be .None (nil), or .Some(String) (and therefore have to be unwrapped).

You are passing that optional String as the argument for String(string: {that optional expression}). The argument may be nil; or it may need unwrapping. The initializer _requires_ a non-nil argument. It’s a righteous error.

The expression

	NSString(string: foo!)

is different; by adding the bang you’ve taken responsibility for the parameter’s not being nil.

Because .lowercaseString returns an implicitly-unwrapped String (String!),

    theURL?.host?.lowercaseString!

tries to unwrap something that is already, syntactically, an unwrapped String.

Quincey — my instinct is that the conditional-unwrap chain necessarily forces left-to-right evaluation, tighter than the . operator. The ! would mean, “if you got this far without short-circuiting, and b returns an optional, then unwrap it.”

As of today’s Swift 1.2b2, the following in a playground:

    let aURL = NSURL(string: "http://wt9t.com/";)!
    NSString(string: aURL.host?.lowercaseString)

complains as you suggest: .host? is potentially nil — that would force the whole expression to be nil, and thus forbidden as a parameter. lowercaseString still gets treated as implicitly unwrapped — so a bang at the end of the whole expression is an attempt to unwrap something the compiler was going to unwrap anyway.




By the way: The use of +[NSString stringWithString:] or -[NSString initWithString:] is a code smell. The result of lowercaseString is declared as immutable, and you aren’t trying to initialize an NSMutableString with it. Foundation (unless I’m missing something) is free to treat it just as it does with -[NSString copy], and simply return the same object with the retain count bumped. Once you get into mutability, the smell goes away, and someone will surely jump in now with an explanation for why it’s needed more often than I think.


	— F



_______________________________________________

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


  • Follow-Ups:
    • Re: Instantiate NSString from NSURL in Swift
      • From: Charles Srstka <email@hidden>
    • Re: Instantiate NSString from NSURL in Swift
      • From: Charles Srstka <email@hidden>
References: 
 >Instantiate NSString from NSURL in Swift (From: Juanjo Conti <email@hidden>)

  • Prev by Date: Re: Instantiate NSString from NSURL in Swift
  • Next by Date: Re: NSOpenPanel() crash in Swift 1.1 -- SOLVED?
  • Previous by thread: Re: Instantiate NSString from NSURL in Swift
  • Next by thread: Re: Instantiate NSString from NSURL in Swift
  • Index(es):
    • Date
    • Thread