Under is the pattern code I exploit:
class Dummy {
let uuid = UUID()
}
func take a look at() {
let dummy = Dummy()
let unmangedOpaquePointer = Unmanaged.passUnretained(dummy).toOpaque()
let fromWithUnsafeAPIPointer = withUnsafePointer(to: dummy, { UnsafeMutableRawPointer(mutating: $0) })
print(unmangedOpaquePointer == fromWithUnsafeAPIPointer) // false
let dummy1 = Unmanaged<Dummy>.fromOpaque(unmangedOpaquePointer).takeUnretainedValue()
let dummy2 = fromWithUnsafeAPIPointer.assumingMemoryBound(to: Dummy.self).pointee
let dummy3 = Unmanaged<Dummy>.fromOpaque(fromWithUnsafeAPIPointer).takeUnretainedValue()
let dummy4 = unmangedOpaquePointer.assumingMemoryBound(to: Dummy.self).pointee
print(dummy1 === dummy2) // true
print(dummy1 === dummy3) // EXC_BAD_ACCESS
print(dummy2 === dummy4) // EXC_BAD_ACCESS
}
take a look at()
- totally different UnsafeMutableRawPointer situations
print(unmangedOpaquePointer == fromWithUnsafeAPIPointer) // false
The results of the above code snippet is “false”. It is type of anticipated. unmangedOpaquePointer and fromWithUnsafeAPIPointer are totally different situations of UnsafeMutableRawPointer
, so they don’t seem to be equal.
Nonetheless, they each level to the identical object dummy right here. How can I take a look at this piece of truth, if unmangedOpaquePointer == fromWithUnsafeAPIPointer
isn’t the proper strategy to obtain it?
- API calls must be paired? Why? What is the distinction between the UnsafeMutableRawPointer returned from
Unmanaged
APIs and thewithUnsafePointer
APIs?
print(dummy1 === dummy2) // true
The print
name says dummy1 and dummy2 retrieved from the 2 pointers are similar (the identical object occasion). Nonetheless dummy1 === dummy3
and dummy2 === dummy4
usually are not runtime legitimate expressions (trigger they each crash).
So it appears the pointer returned by calling an Unmanaged
API ought to solely be used with an Unmanaged
API to retrieve the worth that the pointer factors to. The identical goes for withUnsafePointer
APIs. Why?
With the assistance of @Sweeper, I examined one other model of the pattern code:
class Dummy {
let uuid = UUID()
}
func take a look at() {
var dummy = Dummy()
let unmangedOpaquePointer = Unmanaged.passUnretained(dummy).toOpaque()
withUnsafeMutablePointer(to: &dummy) {
let fromWithUnsafeAPIPointer = UnsafeMutableRawPointer($0)
print(unmangedOpaquePointer == fromWithUnsafeAPIPointer) // false
let dummy1 = Unmanaged<Dummy>.fromOpaque(unmangedOpaquePointer).takeUnretainedValue()
let dummy2 = fromWithUnsafeAPIPointer.assumingMemoryBound(to: Dummy.self).pointee
let dummy3 = Unmanaged<Dummy>.fromOpaque(fromWithUnsafeAPIPointer).takeUnretainedValue()
let dummy4 = unmangedOpaquePointer.assumingMemoryBound(to: Dummy.self).pointee
print(dummy1 === dummy2) // true
print(dummy1 === dummy3) // EXC_BAD_ACCESS
print(dummy2 === dummy4) // EXC_BAD_ACCESS
}
}
take a look at()
This corrects the mistaken manner to make use of withUnsafePointer
APIs. However the consequence is identical.