Swift 3-通过UnsafeMutableRawPointer通过引用传递结构? [英] Swift 3 - Pass struct by reference via UnsafeMutableRawPointer?

查看:127
本文介绍了Swift 3-通过UnsafeMutableRawPointer通过引用传递结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Core Audio -框架中,用户数据可以通过 UnsafeMutableRawPointer?传递到回调中。我想知道如何通过此 UnsafeMutableRawPointer通过引用传递结构。在回调内部进行的更改应反映在回调外部。

In the Core Audio-Framework user data can be passed into callbacks via an UnsafeMutableRawPointer?. I was wondering how to pass a struct by reference via this UnsafeMutableRawPointer?. Changes made inside the callback should be reflected outside the callback.

我建立了一个游乐场进行测试:

I set up a playground to test this:

struct TestStruct {
    var prop1: UInt32
    var prop2: Float64
    var prop3: Bool
}

func printTestStruct(prefix: String, data: TestStruct) {
    print("\(prefix): prop1: \(data.prop1), prop2: \(data.prop2), prop3: \(data.prop3)")
}

func testUnsafeMutablePointer(data: UnsafeMutableRawPointer?) {
    var testStructInFunc = data!.load(as: TestStruct.self)

    printTestStruct(prefix: "In func (pre change)", data: testStructInFunc)

    testStructInFunc.prop1 = 24
    testStructInFunc.prop2 = 1.2
    testStructInFunc.prop3 = false

    printTestStruct(prefix: "In func (post change)", data: testStructInFunc)
}

var testStruct: TestStruct = TestStruct(prop1: 12, prop2: 2.4, prop3: true)

printTestStruct(prefix: "Before call", data: testStruct)

testUnsafeMutablePointer(data: &testStruct)

printTestStruct(prefix: "After call", data: testStruct)

可悲的是,在函数调用后,在 testUnsafeMutablePointer 函数内对 testStruct 所做的任何更改似乎都丢失了。

Sadly it seems like any changes to testStruct made inside the testUnsafeMutablePointer function are lost after the function call.

我当时在想, UnsafeMutableRawPointer 的行为就像是引用引用吗?我错过了什么?

I was thinking, that the UnsafeMutableRawPointer behaves like a pass by reference here? What am I missing out?

推荐答案

您的函数将数据复制到本地结构中,但是
不复制修改回来的数据。因此,在您的特殊情况下,这可能是
的解决方案:

Your function copies the data into a local struct, but does not copy the modified data back. So this would be a possible solution in your special case:

func testUnsafeMutablePointer(data: UnsafeMutableRawPointer?) {
    var testStructInFunc = data!.load(as: TestStruct.self)

    testStructInFunc.prop1 = 24
    testStructInFunc.prop2 = 1.2
    testStructInFunc.prop3 = false

    data!.storeBytes(of: testStructInFunc, as: TestStruct.self)
}

但是请注意,仅当结构仅包含简单
值(如整数和浮点值)时,此方法才有效。像数组或字符串之类的复杂类型
包含指向实际存储区
的不透明指针,不能像这样简单地复制。

But note that this works only if the struct contains only "simple" values likes integers and floating point values. "Complex" types like arrays or strings contain opaque pointers to the actual storage and cannot be simply copied like this.

另一种选择是修改这样的指向结构:

Another option is to modify the pointed-to struct like this:

func testUnsafeMutablePointer(data: UnsafeMutableRawPointer?) {
    let testStructPtr = data!.assumingMemoryBound(to: TestStruct.self)

    testStructPtr.pointee.prop1 = 24
    testStructPtr.pointee.prop2 = 1.2
    testStructPtr.pointee.prop3 = false
}

两个解决方案均假定在调用回调
时该结构仍然存在,因为传递指针并不能确保指向结构的
寿命。

Both solutions assume that the struct still exists when the callback is called, since passing a pointer around does not ensure the lifetime of the pointed-to struct.

作为替代方案,请考虑使用<$ c $的实例c> class 。
通过将保留或未保留的指针传递给实例,可以在回调为活动时控制
对象的生存期,请比较
如何将自己投射到UnsafeMutablePointer 迅速输入

As an alternative, consider to use an instance of a class instead. Passing retained or unretained pointers to the instance allows to control the lifetime of the object while the callback is "active", compare How to cast self to UnsafeMutablePointer<Void> type in swift.

这篇关于Swift 3-通过UnsafeMutableRawPointer通过引用传递结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆