【问题标题】:Swift C callback - takeUnretainedValue or takeRetainedValue for Swift class pointerSwift C 回调 - Swift 类指针的 takeUnretainedValue 或 takeRetainedValue
【发布时间】:2017-11-26 22:57:05
【问题描述】:

我有几个UIViewUITableViewCell。里面我有C回调,例如:

CCallback(bridge(self),
       {(observer, data) -> Void in
          let mySelf = Unmanaged<DetailedView>.fromOpaque(observer!).takeRetainedValue()
           mySelf.fillLoadedData(data: data)
        });

别处

func bridge<T : AnyObject>(_ obj : T) -> UnsafeMutableRawPointer {
    return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque())
}

在 C 中:

void CCalback(void * classPtr, void(*callback)(void *, MyData)){
   //fill data
   callback(classPtr, data)
}

我应该使用takeUnretainedValue 还是takeRetainedValue 结束?据我了解,保留会增加对象引用计数,所以它不会被自动销毁?否则,如果我使用takeUnretainedValue,如果self 是自动释放的,这将崩溃,所以使用takeRetainedValue 会阻止它。我对么?

【问题讨论】:

  • bridge(self) 是什么?
  • @MartinR 代码添加

标签: ios swift memory-management


【解决方案1】:

对象指针可以转换为Unsafe(Mutable)RawPointer(Swift 相当于 C void *) 保留或不保留对象:

let ptr = UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque())
// Does not retain `obj`

let ptr = UnsafeMutableRawPointer(Unmanaged.passRetained(obj).toOpaque())
// Retains `obj`

转换回对象指针(通常在回调中完成 从 C 调用的函数)可以使用或不使用保留:​​

let obj = Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
// Does not consume a retain

let obj = Unmanaged<T>.fromOpaque(ptr).takeRetainedValue()
// Consumes a retain

如果obj 的生命周期是保证,而回调处于活动状态 那么最简单的方法是在两个方向上使用“未保留”的转换。您有责任保留obj,而 回调处于活动状态,例如通过在obj 之前取消注册回调 被取消初始化。

另一种方法是使用passRetained()obj 转换为 一个指针。这保留了对象,因此保持它“活着”。 回调仍然可以使用“未保留”转换来转换 指向对象指针的指针,而不减少保留计数。 但是必须有一个 takeRetainedValue() 调用才能使用 保持。之后,如果没有,对象可以被销毁 其他引用。

更一般地说,每次调用 passRetained(obj) 都会增加保留 count 并且每次调用takeRetainedValue() 都会减少它,因此它们必须适当平衡。

【讨论】:

    猜你喜欢
    • 2022-09-23
    • 2015-05-16
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    相关资源
    最近更新 更多