Swift C回调 - Swift Class Pointer的Takeunretained Value或takeRe



我有几个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)
}

我应该在封闭中使用takeUnretainedValuetakeRetainedValue吗?据我了解,保留将增加对象参考计数,因此不会自动毁灭?否则,如果我使用takeUnretainedValue,如果自动发行了自动,则会崩溃,因此使用takeRetainedValue将阻止它。我对么?

可以将对象指针转换为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(调用的函数可以或不消耗a固定的功能:

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)都会增加保留计数和每个呼叫takeRetainedValue()都会减少它,因此必须正确平衡它们。

最新更新