Yes, the easiest way is to rely on compiler magic for ObjC/C interoperability, 
but it is also important to know what is really happening.

My preferred version of the compiler magic is this actually:

func allZerosUUID() -> String {

    return NSUUID(uuidBytes: [UInt8](repeating: 0, count: 32)).uuidString
}

Which is effectively this:

func allZerosUUID() -> String {

    let allZeros = [UInt8](repeating: 0, count: 32)

    return NSUUID(uuidBytes: allZeros).uuidString
}

(Note the use of let and absence of &).

> On Mar 2, 2017, at 1:33 PM, Russell Finn <rsf...@gmail.com> wrote:
> 
> I agree that the use of `withUnsafeBufferPointer` to get to the contents of 
> an array makes more sense than `withUnsafePointer`, once you discover the 
> concept of a "buffer pointer" (which a new Swift programmer may not do at 
> first).
> 
> However, I note that the following code:
> 
>     func allZerosUUID() -> String {
>         var allZeros = [UInt8](repeating: 0, count: 32)
>         return NSUUID(uuidBytes: &allZeros)
>     }
> 
> also compiles without error and returns the intended value. This appears to 
> be supported by the "Constant Pointers" section of the "Interacting with C 
> APIs" chapter of "Using Swift with Cocoa and Objective-C":  "When a function 
> is declared as taking an `UnsafePointer<Type>` argument, it can accept ... a 
> `[Type]` value, which is passed as a pointer to the start of the array."
> 
> I suspect the availability of `&array` in this context, coupled with an 
> awareness of the existence of `withUnsafePointer(to:)`, is what led my 
> co-worker down the wrong road (and to a puzzling error message); but since we 
> have now discovered two more appropriate ways to write the code in question, 
> perhaps it's not worth worrying about too much.
> 
> Thanks to everyone for the discussion.
> 
> 
> On Wed, Mar 1, 2017 at 7:36 PM, Hooman Mehr <hoo...@mac.com 
> <mailto:hoo...@mac.com>> wrote:
> Your co-worker needs to get passed the learning curve of these “unsafe” APIs 
> and note that Swift arrays are complex data structures. &allZeros does not 
> give you a pointer to a bunch of zero bytes, but a pointer to a struct that 
> contains the private implementation details of allZeros array. 
> 
> Here is the correct way to do it:
> 
> func allZerosUUID() -> String {
> 
>     let allZeros = [UInt8](repeating: 0, count: 32)
> 
>     return allZeros.withUnsafeBufferPointer { NSUUID(uuidBytes: 
> $0.baseAddress).uuidString }
> }
> 
> 
>> On Mar 1, 2017, at 2:35 PM, Russell Finn via swift-users 
>> <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
>> 
>> Thanks to Joe and Quinn for their answers. I have a related followup — a 
>> co-worker learning Swift wrote the following function:
>> 
>>     func allZerosUUID() -> String {
>>         var allZeros = [UInt8](repeating: 0, count: 32)
>>         return withUnsafePointer(to: &allZeros) { zerosPtr in
>>             return NSUUID(uuidBytes: zerosPtr).uuidString
>>         }
>>     }
>> 
>> but was puzzled that Xcode 8.2.1 gave an error "Cannot convert value of type 
>> 'UnsafePointer<_>' to expected argument type 'UnsafePointer<UInt8>!'" on the 
>> line with the NSUUID initializer.  Their expectation was that `zerosPtr` 
>> would be of type `UnsafePointer<UInt8>` because `allZeros` is of type 
>> `[UInt8]`.  
>> 
>> They discovered that they could work around this by adding a call to 
>> `withMemoryRebound`:
>> 
>>     func allZerosUUID() -> String {
>>         var allZeros = [UInt8](repeating: 0, count: 32)
>>         return withUnsafePointer(to: &allZeros) { zerosPtr in
>>             zerosPtr.withMemoryRebound(to: UInt8.self, capacity: 
>> allZeros.count) { zerosPtr in
>>                 return NSUUID(uuidBytes: zerosPtr).uuidString
>>             }
>>         }
>>     }
>> 
>> but felt that this should be unnecessary. Perhaps I'm missing something 
>> simple, but I was unable to explain this compiler behavior; can anyone on 
>> the list do so?
>> 
>> (Yes, I did point out that they could pass `&allZeros` directly to 
>> `NSUUID(uuidBytes:)`.)
>> 
>> Thanks — Russell
>> 
>> _______________________________________________
>> swift-users mailing list
>> swift-users@swift.org <mailto:swift-users@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-users 
>> <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