2017-06-23 19 views
2

私はいくつかのUIViewまたはUITableViewCellを持っています。他Swift Cコールバック - SwiftクラスのポインタのtakeUnretainedValueまたはtakeRetainedValue

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

どこかCで

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

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

は、私が閉鎖にtakeUnretainedValueまたはtakeRetainedValueを使用すべき、私は例えばCコールバックを、持っている内部の?私がこれを理解する限り、オブジェクトの参照カウントを増加させるので、自動破壊されません。そうでない場合、私がtakeUnretainedValueを使用すると、自己が自動リリースされた場合、これはクラッシュするので、takeRetainedValueを使用すると、それが防止されます。私は正しいですか?

+0

「ブリッジ(自己)」とは何ですか? –

+0

@MartinRコードが追加されました –

答えて

2

オブジェクトポインタは、またはオブジェクトを保持せずにUnsafe(Mutable)RawPointer(C void *のスイフト 相当)に変換することができる。

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

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

バック(多くの場合、コールバックで行われたオブジェクト・ポインタへの変換

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

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

objの寿命がグラムである場合:Cから呼び出さ 関数)または保持消費せずにすることができますコールバックがアクティブな間に 最も簡単な方法は、両方向で「未保持」のコンバージョンを使用することです。 コールバックが有効な場合は、objを保持する責任があります。 obj の前にコールバックの登録を解除すると、初期化されません。

代わりに、passRetained()を使用して、objから にポインタを変換します。これはオブジェクトを保持し、したがってそれを「生きている」状態に保ちます。 コールバックは、保持カウントを減らさずに、ポインタにオブジェクトポインタへの を変換するために、「未保持」変換を引き続き使用できます。 しかし、ちょうどを消費するためにtakeRetainedValue()コールが必要です。その後、 という他の参照がない場合、オブジェクトは破棄される可能性があります。

さらに一般的には、passRetained(obj)を呼び出すたびに保持 が増加し、takeRetainedValue()を呼び出すたびに減少しますので、適切に調整する必要があります。

関連する問題