I am trying to access the keys and values in a CFDictionary which is created from a CGImageSource. Here is the definition of the function used to access Keys and Values data:
func CFDictionaryGetKeysAndValues(_ theDict: CFDictionary!,
_ keys: UnsafeMutablePointer<UnsafeRawPointer?>!,
_ values: UnsafeMutablePointer<UnsafeRawPointer?>!)
My problem is with creating the two pointers for the Keys and Values arrays. Also, I am really unsure whether I am declaring the Arrays the correct way. Here is the description of the CFDictionaryGetKeysAndValues keys and values parameters:
A C array of pointer-sized values that, on return, is filled with keys from the theDict. The keys and values C arrays are parallel to each other (that is, the items at the same indices form a key-value pair from the dictionary). This value must be a valid pointer to a C array of the appropriate type and size (that is, a size equal to the count of theDict), or NULL if the keys are not required. If the keys are Core Foundation objects, ownership follows the The Get Rule.
Here is my implementation according to what I understand of the Unsafe pointers API, but it gives me unreliable results:
// Get the CFDictionary and count the number of returned properties
let imageProperties: CFDictionary = CGImageSourceCopyProperties(imageSource, nil)!
let propCount = CFDictionaryGetCount(imageProperties)
// Create a stub UnsafeRawPointer used to initialize Array
let string: String = ""
let stubPointer = UnsafeRawPointer(string)
// Initialize an Array of pointers for the Keys and one for the Values
var aKeys: Array<UnsafeRawPointer> = Array(repeating: stubPointer, count: propCount)
var aValues: Array<UnsafeRawPointer> = Array(repeating: stubPointer, count: propCount)
// Create the pointers and !hopefully! access dictionary Keys and Values
withUnsafePointer(to: &aKeys[0], {(ptr: UnsafePointer<UnsafeRawPointer>?) -> Void in
var ptrKeysM = UnsafeRawPointer(ptr)
let ptrKeys = UnsafeMutablePointer(&ptrKeysM)!
ptrKeys.initialize(to: ptrKeysM, count: propCount)
withUnsafePointer(to: &aValues[0], {(ptr2: UnsafePointer<UnsafeRawPointer>?) -> Void in
var ptrValuesM = UnsafeRawPointer(ptr2)
let ptrValues = UnsafeMutablePointer(&ptrValuesM)!
ptrValues.initialize(to: ptrValuesM, count: propCount)
CFDictionaryGetKeysAndValues(imageProperties, ptrKeys, ptrValues)
})
})
Now this compiles correctly. When the CGImageSource only returns 1 property, everything goes well (ie: the application doesn't crash). However, if the CGImageSource returns more than 1 property, I get the following error after the call to CFDictionaryGetKeysAndValues:
error: memory read failed for 0x1f600
Thread 1: EXC_BAD_ACCESS (code=1, address=0x1f637)
You might have guessed that I am totally new to Swift and I still have not wrapped my head around this API for pointers. From what I understand, the GetKeysAndValues call returns pointers to the Keys and Values which are stored in the aKeys and aValues Arrays. Is this correct? Thank you all for your help.