How to Alloc/Dealloc Unsafe Pointers in Swift

How do you alloc/dealloc unsafe pointers in Swift?

This works, Swift is smart enough to know what to do with the & operator:

let color = UIColor.purpleColor()
var r:CGFloat, g:CGFloat, b:CGFloat, a:CGFloat = 0
color.getRed(&r, green: &g, blue: &b, alpha: &a)
CGContextSetRGBStrokeColor(c, r, g, b, a)

If you really want to do the alloc yourself, use your favorite flavor and construct the pointer like this:

let p = UnsafeMutablePointer<CGFloat>(calloc(1, UInt(sizeof(CGFloat))))
// later don't forget to free(p)

How to dealloc UnsafeMutablePointer referenced from Swift struct

You could wrap the pointer in a class. Something like this:

struct ViewBox {
class WrappedPointer() {
let pointer: UnsafeMutablePointer<UIView>

init() {
pointer = UnsafeMutablePointer<UIView>.alloc(1)
}

deinit {
pointer.dealloc(1)
}
}

let wrappedPointer = WrappedPointer()
}

Automatically handling disposing of unsafe allocated memory in Swift

You can define a class instead and release the memory in deinit:

class Packet {
var memoryBlock : UnsafeRawPointer
init() {
let block = UnsafeMutableRawPointer.allocate(byteCount: 128, alignment: 4)
//someProcessThatFillsTheBuffer (block);
memoryBlock = UnsafeRawPointer(block);
}

deinit {
memoryBlock.deallocate()
}
}

Now instances of Packet are references to an object and can be
passed around. ARC (automatic reference counting) ensures that deinit is called when the last reference to the
object is gone.

Swift 4.1 deinitialize and deallocate(capacity:) deprecated

Yes, that is part of SE-0184 Unsafe[Mutable][Raw][Buffer]Pointer: add missing methods, adjust existing labels for clarity, and remove deallocation size,
which has been implemented in Swift 4.1.

In particular:

Removing capacity from deallocate(capacity:) will end the confusion over what deallocate() does, making it obvious that deallocate() will free the entire memory block at self, just as if free() were called on it.

The old deallocate(capacity:) method should be marked as deprecated and eventually removed since it currently encourages dangerously incorrect code.

How to extract UnsafePointer CGFloat from UnsafePointer CGPoint - Swift

It is unsafe to output pointers like that. As mentioned in comments you should use withUnsafeBufferPointer method to access the underlying buffer:

let points = [
CGPoint(x:1.2, y:3.33),
CGPoint(x:1.5, y:1.21),
CGPoint(x:1.48, y:3.97)
]

let xValues = points.withUnsafeBufferPointer { buffer in
return buffer.map { $0.x }
}

If you need a pointer to the array of CGFloat just use the same method as above:

xValues.withUnsafeBufferPointer { buffer in 
// Do things with UnsafeBufferPointer<CGFloat>
}

A good Swift Pointer tutorial here.


Edit

Here is a working example:

let points = [
CGPoint(x:1.2, y:3.33),
CGPoint(x:1.5, y:1.21),
CGPoint(x:1.48, y:3.97)
]

// Create, init and defer dealoc
let ptr = UnsafeMutablePointer<CGFloat>.allocate(capacity: points.count)
ptr.initialize(repeating: 0.0, count: points.count)
defer {
ptr.deallocate()
}

// Populate pointer
points.withUnsafeBufferPointer { buffer in
for i in 0..<buffer.count {
ptr.advanced(by: i).pointee = buffer[i].x
}
}

// Do things with UnsafeMutablePointer<CGFloat>, for instance:
let buffer = UnsafeBufferPointer(start: ptr, count: points.count)

for (index, value) in buffer.enumerated() {
print("index: \(index), value: \(value)")
}


Related Topics



Leave a reply



Submit