【问题标题】:Swift 3 - Pass struct by reference via UnsafeMutableRawPointer?Swift 3 - 通过 UnsafeMutableRawPointer 通过引用传递结构?
【发布时间】:2017-03-04 12:53:10
【问题描述】:

Core Audio-Framework 中,用户数据可以通过UnsafeMutableRawPointer? 传递到回调中。我想知道如何通过这个UnsafeMutableRawPointer? 传递一个结构引用。回调内部所做的更改应反映在回调外部。

我设置了一个游乐场来测试这个:

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)

遗憾的是,在函数调用后,似乎对 testStruct 内部的任何更改 testUnsafeMutablePointer 都会丢失。

我在想,UnsafeMutableRawPointer 的行为就像这里的引用传递?我错过了什么?

【问题讨论】:

    标签: swift swift3 pass-by-reference core-audio unsafemutablepointer


    【解决方案1】:

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

    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)
    }
    

    但请注意,这仅在结构仅包含“简单”时才有效 values 喜欢整数和浮点值。 “复杂”类型 像数组或字符串一样包含指向实际存储的不透明指针 不能像这样简单复制。

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

    func testUnsafeMutablePointer(data: UnsafeMutableRawPointer?) {
        let testStructPtr = data!.assumingMemoryBound(to: TestStruct.self)
    
        testStructPtr.pointee.prop1 = 24
        testStructPtr.pointee.prop2 = 1.2
        testStructPtr.pointee.prop3 = false
    }
    

    两种解决方案都假设结构体在回调时仍然存在 被调用,因为传递一个指针并不能确保 指向结构的生命周期。

    作为替代方案,请考虑改用class 的实例。 将保留或未保留的指针传递给实例允许控制 回调“活动”时对象的生命周期,比较 How to cast self to UnsafeMutablePointer<Void> type in swift.

    【讨论】:

    • 非常感谢!这绝对为我解决了问题。这里最 Swifty 的解决方案是什么(我假设使用 class,但我对 Swift 还很陌生)?
    • @Herickson:如果没有更多上下文,这很难说。您正在与 C API 交互,因此无论如何都没有纯 Swift。
    猜你喜欢
    • 2013-06-04
    • 2013-05-12
    • 2011-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-13
    • 2019-09-11
    相关资源
    最近更新 更多