Swift Unsafemutablepointer<Unmanaged<Cfstring>> Allocation and Print

Swift UnsafeMutablePointerUnmanagedCFString? allocation and print

I have no experience with CoreMIDI and could not test it, but this is how it should work:

let midiEndPoint = MIDIGetSource(0)
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(midiEndPoint, kMIDIPropertyDisplayName, &property)
if err == noErr {
let displayName = property!.takeRetainedValue() as String
println(displayName)
}

As @rintaro correctly noticed, takeRetainedValue() is the right choice here because it is the callers responsibility to release the string. This is different from the
usual Core Foundation memory management rules, but documented in the
MIDI Services Reference:

NOTE

When passing a Core Foundation object to a MIDI function, the MIDI
function will never consume a reference to the object. The caller
always retains a reference which it is responsible for releasing by
calling the CFRelease function.

When receiving a Core Foundation object as a return value from a MIDI
function, the caller always receives a new reference to the object,
and is responsible for releasing it.

See "Unmanaged Objects" in "Working with Cocoa Data Types" for more information.

UPDATE: The above code works only when compiling in 64-bit mode. In 32-bit mode,
MIDIObjectRef and MIDIEndpointRef are defined as different kind of pointers.
This is no problem in (Objective-)C, but Swift does not allow a direct conversion, an
"unsafe cast" is necessary here:

let numSrcs = MIDIGetNumberOfSources()
println("number of MIDI sources: \(numSrcs)")
for srcIndex in 0 ..< numSrcs {
#if arch(arm64) || arch(x86_64)
let midiEndPoint = MIDIGetSource(srcIndex)
#else
let midiEndPoint = unsafeBitCast(MIDIGetSource(srcIndex), MIDIObjectRef.self)
#endif
var property : Unmanaged<CFString>?
let err = MIDIObjectGetStringProperty(midiEndPoint, kMIDIPropertyDisplayName, &property)
if err == noErr {
let displayName = property!.takeRetainedValue() as String
println("\(srcIndex): \(displayName)")
} else {
println("\(srcIndex): error \(err)")
}
}

What does `UnsafeMutablePointer.initialize()`actually do?

One reason you need initialize(), and the only one as for now maybe, is

for ARC.

You'd better think with local scope variables, when seeing how ARC works:

func test() {
var refVar: RefType = initValue //<-(1)
//...
refVar = newValue //<-(2)
//...
//<-(3) just before exiting the loacl scope
}

For a usual assignment as (2), Swift generates some code like this:

swift_retain(_newValue)
swift_release(_refVar)
_refVar = _newValue

(Assume _refVar and _newValue are unmanaged pseudo vars.)

Retain means incrementing the reference count by 1, and release means decrementing the reference count by 1.


But, think what happens when the initial value assignment as at (1).

If the usual assignment code was generated, the code might crash at this line:

swift_release(_refVar)

because newly allocated region for a var may be filled with garbages, so swift_release(_refVar) cannot be safely executed.

Filling the newly region with zero (null) and release safely ignoring the null could be one solution, but it's sort of redundant and not effective.

So, Swift generates this sort of code for initial value assignment:

(for already retained values, if you know ownership model, owned by you.)

_refVar = _initValue

(for unretained values, meaning you have no ownership yet.)

swift_retain(_initValue)
_refVar = _initValue

This is initialize.

No-releasing the garbage data, and assign an initial value, retaining it if needed.

(The above explanation of "usual assignment" is a little bit simplified, Swift omits swift_retain(_newValue) when not needed.)


When exiting the local scope at (3), Swift just generates this sort of code:

swift_release(_refVar)

So, this is deinitialize.


Of course, you know retaining and releasing are not needed for primitive types like Int, so initialize and deinitialize may be donothing for such types.

And when you define a value type which includes some reference type properties, Swift generates initialize and deinitialize procedures specialized for the type.


The local scope example works for the regions allocated on the stack, and initialize() and deinitialize() of UnsafeMutablePointer works for the regions allocated in the heap.

And Swift is evolving so swift, that you might find another reason for needing initialize() and deinitialize() in the future, you'd better make it a habit to initialize() and deinitialize() all allocated UnsafeMutablePointers of any Pointee types.

Swift2: Correct way to initialise UnsafeMutablePointerUnmanagedCFMutableDictionary? parameter to pass to IORegistryEntryCreateCFProperties

A parameter of the type

UnsafeMutablePointer<Unmanaged<CFMutableDictionary>?>

means that you have to pass a variable of the type

Unmanaged<CFMutableDictionary>?

as an inout-argument with &. On success, you can unwrap the optional
(with optional binding),
convert the unmanaged object to a managed object with
takeRetainedValue(), and finally (if you want), cast the CFMutableDictionary to NSDictionary.

Example:

var props : Unmanaged<CFMutableDictionary>?
if IORegistryEntryCreateCFProperties(entry, &props, kCFAllocatorDefault, 0) == KERN_SUCCESS {
if let props = props {
let dict = props.takeRetainedValue() as NSDictionary
print(dict)
}
}

Convert UnsafeMutablePointerInt16 to UInt8

Casting an Unsafe(Mutable)Pointer<Int16> to UnsafePointer<Int8>
would simply be:

let buffer: UnsafeMutablePointer<Int16> = ...
let count: Int = ... // # of Int16 values

let result = buffer.withMemoryRebound(to: UInt8.self, capacity: 2 * count) {
outputStream.write($0, maxLength: 2 * count)
}

What is UnsafeMutablePointerUnmanagedCMSampleBuffer? in Swift?

As you can see from the declaration of the last parameter,

sbufCopyOut: UnsafeMutablePointer<Unmanaged<CMSampleBuffer>?>

bufferCopy must be declared as optional, not as a implicitly
unwrapped optional:

var bufferCopy: Unmanaged<CMSampleBuffer>?

Note that you have to call takeRetainedValue() on the result,
so the complete solution would be:

var unmanagedBufferCopy: Unmanaged<CMSampleBuffer>?
if CMSampleBufferCreateCopy(kCFAllocatorDefault, sampleBuffer, &unmanagedBufferCopy) == noErr {
let bufferCopy = unmanagedBufferCopy!.takeRetainedValue()
// ...

} else {
// failed
}

Update: In Swift 4 (and probably already in Swift 4),
CMSampleBufferCreateCopy() returns a managed object, therefore
the code simplifies to

var bufferCopy: CMSampleBuffer?
if CMSampleBufferCreateCopy(kCFAllocatorDefault, sampleBuffer, &bufferCopy) == noErr {
// ... use bufferCopy! ...
} else {
// failed
}

Point an UnsafeMutablePointerVoid to itself

On Swift 3:

var somePointer = UnsafeMutableRawPointer(bitPattern: 1)!
somePointer = UnsafeMutableRawPointer(mutating: &somePointer)

print(somePointer)
print(somePointer.load(as: UnsafeMutableRawPointer.self))
// Output of both should be the same.

Swift 2:

Use withUnsafePointer to obtain the pointer to a variable. Then assign that to itself.

var somePointer: UnsafeMutablePointer<Void> = nil
withUnsafePointer(&somePointer) { somePointer = UnsafeMutablePointer($0) }


Related Topics



Leave a reply



Submit