Unsafemutablepointer<Void> to Concrete Object Type

UnsafeMutablePointerVoid to Concrete Object Type

UnsafeMutablePointer has an initializer that takes another UnsafeMutablePointer of another type, the result being the same pointer but to the new type.

So in your case:

let infoPtr = UnsafeMutablePointer<Info>(context)
let info = infoPtr.memory

Beware though this is, as the docs describe it, "a fundamentally unsafe conversion". If the pointer you have is not a pointer to the type you convert it to, or if the memory you are now accessing it is not valid in this context, you may end up accessing invalid memory and your program will get a little crashy.

Typecast UnsafeMutablePointerVoid to UnsafeMutablePointer#Struct type#

I think what you want to say is something like this:

imageData = UnsafeMutablePointer<PixelRGB>.alloc(dataLength)

UnsafeMutablePointerVoid to [NSObject : AnyObject]

If you want to read trackerData from the event, you have to get the user info from the tracking area

if let userInfo = theEvent.trackingArea?.userInfo {
let trackerData = userInfo["myTrackerKey"]! as! NSView
// do something with the view
}

How to avoid a retain cycle when using an array of delegates in Swift

The problem is that weakDelegates is a strong reference and its reference to its elements of type WeakDelegateContainer is a strong reference.

Your situation is why the class NSHashTable exists. Initialize using weakObjects(). This will give you a set of ARC-weak references, each of which will be nilified and removed when the referenced object goes out of existence (with no need for any extra bookkeeping on your part, and no need for your WeakDelegateContainer type).

Your set will have to be typed as holding AnyObject, but you can easily mediate to ensure that you are supplying and retrieving SomeDelegate-conformant objects:

let list = NSHashTable<AnyObject>.weakObjects()
func addToList(_ obj:SomeDelegate) {
list.add(obj)
}
func retrieveFromList(_ obj:SomeDelegate) -> SomeDelegate? {
if let result = list.member(obj) as? SomeDelegate {
return result
}
return nil
}
func retrieveAllFromList() -> [SomeDelegate] {
return list.allObjects as! [SomeDelegate]
}

The function retrieveAllFromList() lists only objects that still exist. Any object that has gone out existence has been changed to nil in the NSHashTable and is not included in allObjects. That is what I mean by "no extra bookkeeping"; the NSHashTable has already done the bookkeeping.

Here is code that tests it:

func test() {
let c = SomeClass() // adopter of SomeDelegate
self.addToList(c)
if let cc = self.retrieveFromList(c) {
cc.someFunction()
}
print(self.retrieveAllFromList()) // one SomeClass object
delay(1) {
print(self.retrieveAllFromList()) // empty
}
}

Alternatively, you can use NSPointerArray. Its elements are pointer-to-void, which can be a little verbose to use in Swift, but you only have to write your accessor functions once (credit to https://stackoverflow.com/a/33310021/341994):

let parr = NSPointerArray.weakObjects()
func addToArray(_ obj:SomeDelegate) {
let ptr = Unmanaged<AnyObject>.passUnretained(obj).toOpaque()
self.parr.addPointer(ptr)
}
func fetchFromArray(at ix:Int) -> SomeDelegate? {
if let ptr = self.parr.pointer(at:ix) {
let obj = Unmanaged<AnyObject>.fromOpaque(ptr).takeUnretainedValue()
if let del = obj as? SomeDelegate {
return del
}
}
return nil
}

Here is code to test it:

    let c = SomeClass()
self.addToArray(c)
for ix in 0..<self.parr.count {
if let del = self.fetchFromArray(at:ix) {
del.someFunction() // called
}
}
delay(1) {
print(self.parr.count) // 1
for ix in 0..<self.parr.count {
if let del = self.fetchFromArray(at:ix) {
del.someFunction() // not called
}
}
}

Interestingly, after our SomeClass goes out of existence, our array's count remains at 1 — but cycling through it to call someFunction, there is no call to someFunction. That is because the SomeClass pointer in the array has been replaced by nil. Unlike NSHashTable, the array is not automatically purged of its nil elements. They do no harm, because our accessor code has guarded against error, but if you would like to compact the array, here's a trick for doing it (https://stackoverflow.com/a/40274426/341994):

    self.parr.addPointer(nil)
self.parr.compact()

How do you translate this enumerateDraggingItemsWithOptions method call to Swift?

The method signature in Swift is

func enumerateDraggingItemsWithOptions(enumOpts: NSDraggingItemEnumerationOptions, 
forView view: NSView, classes
classArray: [AnyObject],
searchOptions: [NSObject : AnyObject],
usingBlock block: (NSDraggingItem!, Int, UnsafeMutablePointer<ObjCBool>) -> Void)
  • We can omit parameters type in callback, because they are get from declaration,
    that makes code more clean
  • The callback is the last parameter so we can use trailing closure syntax

The call to method

sender.enumerateDraggingItemsWithOptions(
.Concurrent,
forView: self,
classes: [NSPasteboardItem.self],
searchOptions: [NSPasteboardURLReadingFileURLsOnlyKey:self])
{(draggingItem, idx, stop) in
// Code here
}

Swift converts C's uint64_t different than it uses its own UInt64 type

This is an update to my earlier answer after reading your updated question and experimenting some more. I believe the problem is an alignment discrepancy between the imported C structure and the one you manually implemented in Swift. The problem can be solved by using a C helper function to get an instance of the C struct from void pointer as was suggested yesterday, which can then be converted to the manually implemented Swift struct.

I've been able to reproduce the problem after creating an abbreviated mock-up of your DeviceState structure that looks like

typedef struct
{
uint16_t revision;
uint16_t client;
uint16_t cmd;
int16_t parameter;
int32_t value;
uint64_t time;
uint8_t stats[8];
uint16_t compoundValueOld;
} APIStruct;

The corresponding hand-crafted Swift native structure is:

struct MyStruct
{
init( _apis : APIStruct)
{
revision = _apis.revision
client = _apis.client
cmd = _apis.cmd
parameter = _apis.parameter
value = _apis.value
time = _apis.time
stats = _apis.stats
compoundValueOld = _apis.compoundValueOld
}

var revision : UInt16
var client : UInt16
var cmd : UInt16
var parameter : Int16
var value : Int32
var time : UInt64
var stats : (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8);
var compoundValueOld : UInt16
}

The C framework you are working with could have been compiled using a different struct packing, resulting in a non-matching alignment. I used

#pragma pack(2) 

in my C code to break the bit-matching between the Swift's native and imported C struct.

If I do something like

func swiftCallBackVoid( p: UnsafeMutablePointer<Void> )
{
...
let _locMS:MyStruct = (UnsafeMutablePointer<MyStruct>(p)).memory
...
}

the data in _locMS is different from what was placed there by C code. This problem only occurs if I change struct packing using a pragma in my C code; the above unsafe conversion works fine if the default alignment is used. One can solve this problem as follows:

let _locMS:MyStruct = MyStruct(_apis: (UnsafeMutablePointer<APIStruct>(p)).memory)

BTW, the way Swift imports the C struct, the array members become tuples; this can be seen from the fact that tuple notation has to be used to access them in Swift.

I have a sample Xcode project illustrating all this that I've placed on github:

https://github.com/omniprog/xcode-samples

Obviously, the approach of using a helper C function to get APIStruct from a void pointer and then converting the APIStruct to MyStruct may or may not be an option, depending on how the structures are used, how large they are, and on the performance requirements of the application. As you can tell, this approach involves some copying of the structure. Other approaches, I think, include writing a C-layer between Swift code and the 3rd party C framework, studying the memory layout of the C structure and accessing it in creative ways (may break easily), using the imported C struct more extensively in your Swift code, etc...

Here is a way to share data between C and Swift code without unnecessary copying and with changes made in Swift visible to C code. With the following approach, however, it's imperative to be aware of object lifetime and other memory management issues. One can create a class as follows:

// This typealias isn't really necessary, just a convenience
typealias APIStructPtr = UnsafeMutablePointer<APIStruct>

struct MyStructUnsafe
{
init( _p : APIStructPtr )
{
pAPIStruct = _p
}

var time: UInt64 {
get {
return pAPIStruct.memory.time
}
set( newVal ) {
pAPIStruct.memory.time = newVal
}
}
var pAPIStruct: APIStructPtr
}

Then we can use this structure as follows:

func swiftCallBackVoid( p: UnsafeMutablePointer<Void> )
{
...
var _myUnsafe : MyStructUnsafe = MyStructUnsafe(_p: APIStructPtr(p))
...
_myUnsafe.time = 9876543210 // this change is visible in C code!
...
}

How to remove KVO observer from tableViewCell?

Implement the deinit method and put ignoreFrameChanges() in it

deinit
{
ignoreFrameChanges()
}

The method is called before the object will be deallocated

Swift function object wrapper in apple/swift

I believe these details are mainly part of the implementation of Swift's IRGen – I don't think you'll find any friendly structs in the source showing you the full structure of various Swift function values. Therefore if you want to do some digging into this, I would recommend examining the IR emitted by the compiler.

You can do this by running the command:

xcrun swiftc -emit-ir main.swift | xcrun swift-demangle > main.irgen

which will emit the IR (with demangled symbols) for a -Onone build. You can find the documentation for LLVM IR here.

The following is some interesting stuff that I've been able to learn from going through the IR myself in a Swift 3.1 build. Note that this is all subject to change in future Swift versions (at least until Swift is ABI stable). It goes without saying that the code examples given below are only for demonstration purposes; and shouldn't ever be used in actual production code.


Thick function values

At a very basic level, function values in Swift are simple things – they're defined in the IR as:

%swift.function = type { i8*, %swift.refcounted* }

which is the raw function pointer i8*, along with a pointer to its context %swift.refcounted*, where %swift.refcounted is defined as:

%swift.refcounted = type { %swift.type*, i32, i32 }

which is the structure of a simple reference-counted object, containing a pointer to the object's metadata, along with two 32 bit values.

These two 32 bit values are used for the reference count of the object. Together , they can either represent (as of Swift 4):

  • The strong and unowned reference count of the object + some flags, including whether the object uses native Swift reference counting (as opposed to Obj-C reference counting), and whether the object has a side table.

or

  • A pointer to a side table, which contains the above, plus the weak reference count of the object (on forming a weak reference to an object, if it doesn't already have a side table, one will be created).

For further reading on the internals of Swift reference counting, Mike Ash has a great blog post on the subject.

The context of a function usually adds extra values onto the end of this %swift.refcounted structure. These values are dynamic things that the function needs upon being called (such as any values that it has captured, or any parameters that it has been partially applied with). In quite a few cases, function values won't need a context, so the pointer to the context will simply be nil.

When the function comes to be called, Swift will simply pass in the context as the last parameter. If the function doesn't have a context parameter, the calling convention appears to allow it to be safely passed anyway.

The storing of the function pointer along with the context pointer is called a thick function value,
and is how Swift usually stores function values of known type (as opposed to a thin function value which is just the function pointer).

So, this explains why MemoryLayout<(Int) -> Int>.size returns 16 bytes – because it's made up of two pointers (each being a word in length, i.e 8 bytes on a 64 bit platform).

When thick function values are passed into function parameters (where those parameters are of non-generic type), Swift appears to pass the raw function pointer and context as separate parameters.


Capturing values

When a closure captures a value, this value will be put into a heap-allocated box (although the value itself can get stack-promoted in the case of a non-escaping closure – see later section). This box will be available to the function through the context object (the relevant IR).

For a closure that just captures a single value, Swift just makes the box itself the context of the function (no need for extra indirection). So you'll have a function value which looks like a ThickFunction<Box<T>> from the following structures:

// The structure of a %swift.function.
struct ThickFunction<Context> {

// the raw function pointer
var ptr: UnsafeRawPointer

// the context of the function value – can be nil to indicate
// that the function has no context.
var context: UnsafePointer<Context>?
}

// The structure of a %swift.refcounted.
struct RefCounted {

// pointer to the metadata of the object
var type: UnsafeRawPointer

// the reference counting bits.
var refCountingA: UInt32
var refCountingB: UInt32
}

// The structure of a %swift.refcounted, with a value tacked onto the end.
// This is what captured values get wrapped in (on the heap).
struct Box<T> {
var ref: RefCounted
var value: T
}

In fact, we can actually verify this for ourselves by running the following:

// this wrapper is necessary so that the function doesn't get put through a reabstraction
// thunk when getting typed as a generic type T (such as with .initialize(to:))
struct VoidVoidFunction {
var f: () -> Void
}

func makeClosure() -> () -> Void {
var i = 5
return { i += 2 }
}

let f = VoidVoidFunction(f: makeClosure())

let ptr = UnsafeMutablePointer<VoidVoidFunction>.allocate(capacity: 1)
ptr.initialize(to: f)

let ctx = ptr.withMemoryRebound(to: ThickFunction<Box<Int>>.self, capacity: 1) {
$0.pointee.context! // force unwrap as we know the function has a context object.
}

print(ctx.pointee)
// Box<Int>(ref:
// RefCounted(type: 0x00000001002b86d0, refCountingA: 2, refCountingB: 2),
// value: 5
// )

f.f() // call the closure – increment the captured value.

print(ctx.pointee)
// Box<Int>(ref:
// RefCounted(type: 0x00000001002b86d0, refCountingA: 2, refCountingB: 2),
// value: 7
// )

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

We can see that by calling the function between printing out the value of the context object, we can observe the changing in value of the captured variable i.

For multiple captured values, we need extra indirection, as the boxes cannot be stored directly as the given function's context, and may be captured by other closures. This is done by adding pointers to the boxes to the end of a %swift.refcounted.

For example:

struct TwoCaptureContext<T, U> {

// reference counting header
var ref: RefCounted

// pointers to boxes with captured values...
var first: UnsafePointer<Box<T>>
var second: UnsafePointer<Box<U>>
}

func makeClosure() -> () -> Void {
var i = 5
var j = "foo"
return { i += 2; j += "b" }
}

let f = VoidVoidFunction(f: makeClosure())

let ptr = UnsafeMutablePointer<VoidVoidFunction>.allocate(capacity: 1)
ptr.initialize(to: f)

let ctx = ptr.withMemoryRebound(to:
ThickFunction<TwoCaptureContext<Int, String>>.self, capacity: 1) {
$0.pointee.context!.pointee
}

print(ctx.first.pointee.value, ctx.second.pointee.value) // 5 foo

f.f() // call the closure – mutate the captured values.

print(ctx.first.pointee.value, ctx.second.pointee.value) // 7 foob

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

Passing functions into parameters of generic type

You'll note that in the previous examples, we used a VoidVoidFunction wrapper for our function values. This is because otherwise, when being passed into a parameter of generic type (such as UnsafeMutablePointer's initialize(to:) method), Swift will put a function value through some reabstraction thunks in order to unify its calling convention to one where the arguments and return are passed by reference, rather than value (the relevant IR).

But now our function value has a pointer to the thunk, rather than the actual function we want to call. So how does the thunk know which function to call? The answer is simple – Swift puts the function that we want to the thunk to call in the context itself, which will therefore look like this:

// the context object for a reabstraction thunk – contains an actual function to call.
struct ReabstractionThunkContext<Context> {

// the standard reference counting header
var ref: RefCounted

// the thick function value for the thunk to call
var function: ThickFunction<Context>
}

The first thunk that we go through has 3 parameters:

  1. A pointer to where the return value should be stored
  2. A pointer to where the arguments for the function are located
  3. The context object which contains the actual thick function value to call (such as shown above)

This first thunk just extracts the function value from the context, and then calls a second thunk, with 4 parameters:

  1. A pointer to where the return value should be stored
  2. A pointer to where the arguments for the function are located
  3. The raw function pointer to call
  4. The pointer to the context of the function to call

This thunk now retrieves the arguments (if any) from the argument pointer, then calls the given function pointer with these arguments, along with its context. It then stores the return value (if any) at the address of the return pointer.

Like in the previous examples, we can test this like so:

func makeClosure() -> () -> Void {
var i = 5
return { i += 2 }
}

func printSingleCapturedValue<T>(t: T) {

let ptr = UnsafeMutablePointer<T>.allocate(capacity: 1)
ptr.initialize(to: t)

let ctx = ptr.withMemoryRebound(to:
ThickFunction<ReabstractionThunkContext<Box<Int>>>.self, capacity: 1) {
// get the context from the thunk function value, which we can
// then get the actual function value from, and therefore the actual
// context object.
$0.pointee.context!.pointee.function.context!
}

// print out captured value in the context object
print(ctx.pointee.value)

ptr.deinitialize()
ptr.deallocate(capacity: 1)
}

let closure = makeClosure()

printSingleCapturedValue(t: closure) // 5
closure()
printSingleCapturedValue(t: closure) // 7

Escaping vs. non-escaping capture

When the compiler can determine that the capture of a given local variable doesn't escape the lifetime of the function it's declared in, it can optimise by promoting the value of that variable from the heap-allocated box to the stack (this is a guaranteed optimisation, and occurs in even -Onone). Then, the function's context object need only store a pointer to the given captured value on the stack, as it is guaranteed not to be needed after the function exits.

This can therefore be done when the closure(s) capturing the variable are known not to escape the lifetime of the function.

Generally, an escaping closure is one that either:

  • Is stored in a non-local variable (including being returned from the function).
  • Is captured by another escaping closure.
  • Is passed as an argument to a function where that parameter is either marked as @escaping, or is not of function type (note this includes composite types, such as optional function types).

So, the following are examples where the capture of a given variable can be considered not to escape the lifetime of the function:

// the parameter is non-escaping, as is of function type and is not marked @escaping.
func nonEscaping(_ f: () -> Void) {
f()
}

func bar() -> String {

var str = ""

// c doesn't escape the lifetime of bar().
let c = {
str += "c called; "
}

c();

// immediately-evaluated closure obviously doesn't escape.
{ str += "immediately-evaluated closure called; " }()

// closure passed to non-escaping function parameter, so doesn't escape.
nonEscaping {
str += "closure passed to non-escaping parameter called."
}

return str
}

In this example, because str is only ever captured by closures that are known not to escape the lifetime of the function bar(), the compiler can optimise by storing the value of str on the stack, with the context objects storing only a pointer to it (the relevant IR).

So, the context objects for each of the closures1 will look like Box<UnsafePointer<String>>, with pointers to the string value on the stack. Although unfortunately, in a Schrödinger-like manner, attempting to observe this by allocating and re-binding a pointer (like before) triggers the compiler to treat the given closure as escaping – so we're once again looking at a Box<String> for the context.

In order to deal with the disparity between context objects that hold pointer(s) to the captured values rather than holding the values in their own heap-allocated boxes – Swift creates specialised implementations of the closures that take pointers to the captured values as arguments.

Then, a thunk is created for each closure that simply takes in a given context object, extracts the pointer(s) to the captured values from it, and passes this onto the specialised implementation of the closure. Now, we can just have a pointer to this thunk along with our context object as the thick function value.

For multiple captured values that don't escape, the additional pointers are simply added onto the end of the box, i.e

struct TwoNonEscapingCaptureContext<T, U> {

// reference counting header
var ref: RefCounted

// pointers to captured values (on the stack)...
var first: UnsafePointer<T>
var second: UnsafePointer<U>
}

This optimisation of promoting the captured values from the heap to the stack can be especially beneficial in this case, as we're no longer having to allocate separate boxes for each value – such as was the case previously.

Furthermore it's worth noting that lots of cases with non-escaping closure capture can be optimised much more aggressively in -O builds with inlining, which can result in context objects being optimised away entirely.



1. Immediately-evaluated closures actually don't use a context object, the pointer(s) to the captured values are just passed directly to it upon calling.

Swift - how to use malloc?

You need to implement a bridging header when you use ObjC or C from Swift. The functions exported by your bridging header are then available in your Swift app/module. See here, for the overview.

If you just need to "call some code" on the C-side, then the functions exported from C are basically just wrappers for Swift. However, if you need to interact with the data returned from those functions -- especially if malloc'd and not a simple primitive -- Swift has a number of C related types ready for your use (see here for specifics).

Furthermore, if you're trying to wrap or interact with C++ code, you can't directly do so from Swift. You have to setup an initial interface with ObjC or C for the C++ code, and then bridge that to Swift. Not really fun at all, but thankfully it's not as common a use case as bridging ObjC (primarily) or C.

... and for what it's worth, unless you need low level Core Audio for some reason (granted, like porting an app you already have), AVAudioEngine (iOS8+) is so much simpler for any applicable use case than Core Audio, and is readily available in Swift.



Related Topics



Leave a reply



Submit