> 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 
<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

Reply via email to