我有几个UIView
或UITableViewCell
。在里面我有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
会阻止它。我对么?
答案 0 :(得分:2)
对象指针可以转换为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)调用的函数可以使用或不使用retain:
let obj = Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
// Does not consume a retain
let obj = Unmanaged<T>.fromOpaque(ptr).takeRetainedValue()
// Consumes a retain
如果回调处于活动状态,obj
的生命周期保证
那么最简单的方法就是使用&#34;未获取的&#34;两个方向的转换。你有责任保留obj
回调是有效的,例如通过在obj
之前取消注册回调
被取消初始化。
另一种方法是使用passRetained()
将obj
转换为
一个指针。这样就可以保留物体,从而使物体保持活力#34;
回调仍然可以使用&#34;未返回的&#34;转换为转换
指向对象指针的指针,不会减少保留计数。
但是必须有一个takeRetainedValue()
调用来消费
保留。之后,如果没有,则可以销毁该对象
其他参考文献。
更一般地说,每次拨打passRetained(obj)
都会增加保留
计数和每次调用takeRetainedValue()
会减少它,因此它们必须正确平衡。