Thanks Rod, very enlightening! Regards, Rien
Site: http://balancingrock.nl Blog: http://swiftrien.blogspot.com Github: http://github.com/Swiftrien Project: http://swiftfire.nl > On 06 Jan 2017, at 15:19, Rod Brown <rodney.bro...@icloud.com> wrote: > > >> On 7 Jan 2017, at 12:50 am, Rien <r...@balancingrock.nl> wrote: >> >> Hmm, that is interesting to know. I had not realised that URL is in fact NOT >> a NSURL but a new type that is based on NSURL (and can be toll-free bridged >> I assume?). > > URL a new Type, which internally wraps a NSURL reference. It is practically > toll free bridged, as URL is simply a struct wrapper placed around the > internal reference. > > NSURL is a class and has reference semantics. That is, if you change the URL, > it would change all URLs with the same reference. This is why NSURL doesn’t > allow mutation. If you look at the NSURL API, it has a lot of methods like > “URLByAppendingPathComponent” which import into Swift 3 as > “appendingPathComponent()”. These return *copies* of the NSURL reference, > with the applied mutation. > > URL is a struct and has value semantics. That is, if you change the URL, it > only changes the struct at this place and has no wider effects. Thus, there > are new mutating methods on this struct, love “appendPathExtension()” and > “appendPathComponent()” that allow mutation, because it only affects this > local copy. These methods internally actually use the > appendingPathComponent() method to get a replacement NSURL instance internal > of the struct. > > The URL struct mutating behaviour makes URL manipulation much more convenient > in Swift 3. > >> I also presume that the same is true for Data/NSData, Date/NSDate etc? > > Correct. Except Date/NSDate is actually a slight edge case. > > Instead of Date simply wrapping an NSDate, it actually only wraps the > NSDate’s timeIntervalSinceReferenceDate. This is because there’s no point > wrapping the internal reference to the NSDate, it’s more performant simply to > wrap the NSTimeInterval (a Double) and get true struct properties. You should > note that this means when you cast from Date to NSDate, you need to create a > new reference each time. > > This becomes a bigger issue for IndexPath/NSIndexPath which also does this. > Casting between NSIndexPath and IndexPath can be somewhat less performant, as > it can hold an arbitrarily large number of integers. It’s also interesting to > note that NSIndexPath has an optimisations that could make it perform better > than IndexPath: NSIndexPath uses tagged pointers for row/item and section > conveniences on iOS, and IndexPath does not. This should really not concern > you generally, but you should avoid casting backwards and forwards between > the Struct and Reference types a lot as this could cause unnecessary > performance problems. > > If you want to see the struct overlay for Foundation for yourself, take a > look here: > https://github.com/apple/swift/tree/master/stdlib/public/SDK/Foundation > >> >> (Failure on my part, as I did of course know that the .path method/var is in >> fact different on URL and NSURL) >> >> Regards, >> Rien >> >> Site: http://balancingrock.nl >> Blog: http://swiftrien.blogspot.com >> Github: http://github.com/Swiftrien >> Project: http://swiftfire.nl >> >> >> >> >>> On 06 Jan 2017, at 14:39, Rod Brown via swift-users <swift-users@swift.org> >>> wrote: >>> >>> Hi Jan, >>> >>> The Swift 3 URL struct has a modernized version of the NSURL API which >>> works far better in Swift. This replaces “getResourceValue(…)” with the API >>> you mentioned: “resourceValues(forKeys:)”. >>> >>> >>> Previously, in Swift 2, you had to use an separate value, use >>> AutoreleasingUnsafeMutablePointers, conditionally cast and then hope you >>> got the value, and that you used the correct typecast for the key you were >>> asking for: >>> >>> let url = NSURL(fileURLWithPath: "/Users/me/Desktop/File.png") >>> >>> var fileType: AnyObject? = nil >>> do { >>> try url.getResourceValue(&fileType, forKey: NSURLTypeIdentifierKey) >>> >>> if let type = fileType as? String { >>> // Use the file type here >>> } else { >>> // Handle error >>> } >>> } catch { >>> // Handle error >>> } >>> >>> >>> In Swift 3 with the new Swift URL, the resourceValues(forKeys:) creates a >>> struct with optional type safe properties representing each resource key >>> type, and returns it, allowing you to use if let syntax: >>> >>> let url = URL(fileURLWithPath: "/Users/me/Desktop/File.png") >>> if let resourceValues = try? url.resourceValues(forKeys: >>> [.typeIdentifierKey]), >>> let fileType = resourceValues.typeIdentifier { >>> // Use the file type here >>> } >>> >>> >>> This is a much cleaner, clearer, and type-safe API. >>> >>> If you want to use the old API, you can simply cast back to NSURL if you >>> require the old behaviour. That said, the new one should serve all your >>> needs and make things so much easier so I recommend you give it a go. >>> >>> Hope this helps, >>> >>> Rod >>> >>> >>> >>> >>>> On 6 Jan 2017, at 6:36 am, J.E. Schotsman via swift-users >>>> <swift-users@swift.org> wrote: >>>> >>>> Hello, >>>> >>>> Is getResourceValue a method or URL or only on NSURL? >>>> After migrating a project to Swift 3 I have code like >>>> >>>> var file:URL >>>> file.getResourceValue(...) // compiles! >>>> >>>> From the documentation and the headers I get the impression that this >>>> should not compile! >>>> >>>> TIA, >>>> >>>> Jan E. >>>> _______________________________________________ >>>> swift-users mailing list >>>> swift-users@swift.org >>>> https://lists.swift.org/mailman/listinfo/swift-users >>> >>> _______________________________________________ >>> swift-users mailing list >>> swift-users@swift.org >>> https://lists.swift.org/mailman/listinfo/swift-users >> > _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users