How to Use Unsafemutablepointer in Swift 3

How to use UnsafeMutablePointer in Swift 3?

I recommend you to work with Data rather than NSData in Swift 3.

var keyData = Data(count: 64)
let result = keyData.withUnsafeMutableBytes {mutableBytes in
SecRandomCopyBytes(kSecRandomDefault, keyData.count, mutableBytes)
}

withUnsafeMutableBytes(_:) is declared as a generic method, so, in simple cases such as this, you can use it without specifying element type.

How to use UnsafeMutablePointerT? in swift 3

The behaviour of your program is undefined.

allocate() returns uninitialized memory:

/// Allocates and points at uninitialized aligned memory for `count`
/// instances of `Pointee`.
///
/// - Postcondition: The pointee is allocated, but not initialized.
public static func allocate(capacity count: Int) -> UnsafeMutablePointer<Pointee>

You have to initialize it before use
(and deinitialize before freeing the memory):

let ref = UnsafeMutablePointer<TestStruct?>.allocate(capacity: 1)
ref.initialize(to: TestStruct())

foo(ptr: ref)
bar(ptr: ref.pointee)

ref.deinitialize()
ref.deallocate(capacity: 1)

Here is another example where not initializing the memory actually
leads to a crash:

class TestClass {
init() { print("init") }
deinit { print("deinit") }
}

let ptr = UnsafeMutablePointer<TestClass>.allocate(capacity: 1)
ptr.pointee = TestClass()

The assignment statement expects that ptr.pointee is in the initialized state
and points to a TestClass instance. Because of ARC (automatic
reference counting), the previously pointed-to object is released
when assigning a new value. That crashes if ptr.pointee is
uninitialized.

UnsafeMutablePointer in Swift 3

Your code is using NSMutableData in a bad manner. You should use mutableBytes rather than bytes.

To work with UnsafeMutableRawPointer, check the latest reference.

UnsafeMutableRawPointer

You can find storeBytes(of:toByteOffset:as:) method.

func storeBytes(of: T, toByteOffset: Int, as: T.Type)

Declaration

func storeBytes<T>(of value: T, toByteOffset offset: Int = default, as: T.Type)

Seems the second parameter is optional, so you can write something like this:

func writeUInt32(value:UInt32) {
guard let data = NSMutableData(length: 4) else { return }
data.mutableBytes.storeBytes(of: CFSwapInt32BigToHost(value), as: UInt32.self)
writeData(data)
}

Or if you want to work with new data type Data:

func writeUInt32(value:UInt32) {
var tempValue = CFSwapInt32BigToHost(value)
let data = Data(bytes: &tempValue, count: MemoryLayout<UInt32>.size)
writeData(data as NSData)
}

Error in UnsafeMutablePointer in swift3

Assuming that buffer is a AudioBuffer from the AVFoundation
framework: buffer.mData is a "optional raw pointer"
UnsafeMutableRawPointer?, and in Swift 3 you have to bind
the raw pointer to a typed pointer:

let buffer: AudioBuffer = ...

if let mData = buffer.mData {
let numSamples = Int(buffer.mDataByteSize)/MemoryLayout<Int16>.size
let samples = UnsafeMutableBufferPointer(start: mData.bindMemory(to: Int16.self, capacity: numSamples),
count: numSamples)
// ...
}

See SE-0107 UnsafeRawPointer API
for more information about raw pointers.

UnsafeMutablePointerCFTypeRef in Swift 3

In your case, you do not need to use withMemoryRebound or withUnsafeMutablePointer(to:).

Instead, you can just use

var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)

if status == noErr, let data = result as? Data {
//use data...
}

Generally, when you need to pass an UnsafeMutablePointer<T> to a function, declare a variable of type T and pass it as an inout argument &variable. In your case, T is CFTypeRef?, and in Swift 3, CFTypeRef is just a typealias of AnyObject.


Even in Swift 2.2, you did not need to use withUnsafeMutablePointer

var result: AnyObject?  
let status = SecItemCopyMatching(query, &result)


Related Topics



Leave a reply



Submit