0

To convert from UnsafeMutableRawPointer to UnsafeMutablePointer, both the approach works. (I'm using Swift 5.2)

// Approach 1
let unsafeMutablePointer = UnsafeBufferPointer(
    start: unsafeMutableRawPointer.assumingMemoryBound(to: UInt8.self), count: Int(size.width * size.height * 4))


// Approach 2
let unsafeMutablePointer = unsafeMutableRawPointer
    .bindMemory(to: UInt8.self, capacity: Int(size.width * size.height * 4))

Are they the same? Or they are meant for different purpose? (when to use which?)

I also notice for Approach 2, even if I give the wrong capacity (e.g. 0), it still works. Is it automatically assign the minimum needed capacity from the unsafeMutableRawPointer?

let unsafeMutablePointer = unsafeMutableRawPointer
    .bindMemory(to: UInt8.self, capacity: 0)
Charlton Provatas
  • 2,184
  • 25
  • 18
Elye
  • 53,639
  • 54
  • 212
  • 474
  • Can you elaborate a bit on use-case here? Based on the code snippet it looks like a better abstraction would be `UnsafeMutableBufferPointer` instead; do you need to interface with a C API that requires `UnsafeMutablePointer` specifically? Also, where is the underlying raw pointer coming from? (In general `bind`ing memory is unsafe unless you're pretty careful about the underlying data. See https://developer.apple.com/videos/play/wwdc2020/10167/ for a bit more) – Itai Ferber Oct 25 '20 at 13:07
  • Thanks @ItaiFerber. The use case is as per https://stackoverflow.com/a/64522645/3286489, where I'm getting data from CGContext, and convert it to Int8 for usage. Hope that provides further context. Both approaches above works, and I'm wonder if one is more appropriate over the other. I'm concern that for Approach 2, with 0 capacity, it is still working... – Elye Oct 25 '20 at 23:27
  • Since you are getting a buffer from another source without copying the data, `bindMemory` call is truly safe, since a `bind` operation assumes the underlying data is truly untyped at the source, which is not guaranteed. (If this helps a little: Swift's pointer aliasing rules are even stricter than C's, and once a buffer of memory is bound to a given type, it is permanently bound until deallocation. Since you can't guarantee the typing of the buffer, it's not recommended you use this.) I suggest watching the linked WWDC video for a full explanation. – Itai Ferber Oct 26 '20 at 00:30
  • Can you elaborate on how you specifically want to use the buffer? (For instance, if you're not actually looking to write to the memory, `UnsafeRawBufferPointer` would be safer to use since the memory remains untyped, and you can load values from anywhere as any type safely.) Since `UInt8` is a trivial type, it _should_ in practice be okay to go with approach #1, because you're not binding the memory yourself, but expressing to Swift that it is _already bound_ coming from somewhere else, and this IIRC safe for trivial types. – Itai Ferber Oct 26 '20 at 00:35
  • Thanks, @ItaiFerber. See if I get it right - If I am not copying, then using `bindMemory` is safe. - If I am not modifying, then using `UnsafeRawBufferPointer` is safe. In my case, I'm not copying and modifying, so both should be safe to use. Is that right? My experience is more towards Android, and relatively new towards iOS, if you could recommend which WWDC video to check out, that will benefit a lot. Appreciate it! – Elye Oct 26 '20 at 01:54
  • Close, but not quite — I should have been more explicit. If you don't copy the buffer, it _isn't_ safe to call `bindMemory` because you don't own it (imagine it as a mutating operation). However, if you know from the source what the underlying data type is, it _is_ safe to call `assumingMemoryBound(to:)` as long as the types match. `UnsafeRawBufferPointer` is _always_ safe to use, but isn't mutable; for writing you can use `UnsafeMutableRawBufferPointer`, and that is also always safe since you're writing raw bytes. Since you're working with `UInt8` anyway, the raw buffers might suit your needs – Itai Ferber Oct 26 '20 at 13:41
  • And the WWDC video I referenced is the link in my first comment above. The whole pointer situation is very confusing (esp. coming from other languages), but the video should clear up a lot! – Itai Ferber Oct 26 '20 at 13:42

0 Answers0