2016-03-23 6 views
6

ARCでは、オブジェクトの強い参照のすべてをnilに設定するだけで、オブジェクトの割り当てを解除できます。 UnsafePointerまたはUnsafeMutablePointerAutoreleasingUnsafeMutablePointerの割り当てを解除する必要がありますか?もしそうなら、どうですか?

、私は明示的にメモリを管理する必要があります。

let buffer = sizeof(Int8) * 4 
var ptr = UnsafeMutablePointer<Void>.alloc(buffer) 
defer { 
    ptr.destroy() 
    ptr.dealloc(someVal) 
    ptr = nil 
} 

しかし、ドキュメントがAutoreleasingUnsafeMutablePointerオブジェクトに対して曖昧です。私はdestroyまたはdeallocAutoreleasingUnsafeMutablePointerに明示的に呼び出すことはできません。

var ptr: AutoreleasingUnsafeMutablePointer<Void> = nil 
defer { 
    ptr = nil 
} 

// assign something to ptr 

名前は、それがスコープ外に落ちた後、それが自動解放されることを意味し、私はそれが自動解放されるためにはAutoreleasingUnsafeMutablePointernilに設定する必要がありますか?

ここでは、AutoreleasingUnsafeMutablePointerを使用して、ランタイムによって現在ロードされているすべてのクラスのリストを取得する例を示します。 Objective-Cランタイムのパワーを呼び出すときに、いくつかの機能だけではなく、UnsafeMutablePointerAutoreleasingUnsafeMutablePointerを必要とすることに注意してください:

var numClasses: Int32 = 0 
var allClasses: AutoreleasingUnsafeMutablePointer<AnyClass?> = nil 
defer { 
    allClasses = nil // is this required? 
} 

numClasses = objc_getClassList(nil, 0) 

if numClasses > 0 { 
    var ptr = UnsafeMutablePointer<AnyClass>.alloc(Int(numClasses)) 
    defer { 
     ptr.destroy() 
     ptr.dealloc(Int(numClasses)) 
     ptr = nil 
    } 
    allClasses = AutoreleasingUnsafeMutablePointer<AnyClass?>.init(ptr) 
    numClasses = objc_getClassList(allClasses, numClasses) 

    for i in 0 ..< numClasses { 
     if let currentClass: AnyClass = allClasses[Int(i)] { 
      print("\(currentClass)") 
     } 
    } 
} 
+0

残念ながら私は答えを持っていないが、それはスコープの外に落ちたとき、それが処理されなかった場合、私は驚くだろう。 –

答えて

5

あなたはnilにそれを設定する必要はありません。自動解放されたポインタから構築されているはずです(正しく構築されていれば、それ自体を解放します)。同時に、現在のスタックフレームを超えて保持しないでください。 AutoreleasingUnsafeMutablePointerはオブジェクトを存続させません。囲みオートリリースプールがポップされると、ラップされたオブジェクトは解放され、おそらく割り当てが解除されます。名前のように:安全でないです。

はスウィフト(:それは本当にUnsafeMutablePointerだとCヘッダインポートが間違い、以下を参照してくださいをした場合を除き、編集)でAutoreleasingUnsafeMutablePointer自分自身を作成することはありませんで問題を避けてください。正しく使用している場合は、SwiftのinoutとObjective-Cのreturn-by-pointerパラメータの間に透明な接着剤が必要です。

通常、含まれるタイプに一致するvarを作成し、inoutで渡します。

あなたが関数を呼び出すにしたい場合:

func someFunction(obj: AutoreleasingUnsafeMutablePointer<AnyObject?>) 

を、あなたはこのようにそれを呼び出す:

var myObject: AnyObject? = nil 
someFunction(&AnyObject) 

、すべてがうまくいきます。

AutoreleasingUnsafeMutablePointerを保持する必要がある他の状況は認識していません。 nil以外のSwift側では、手動で構築する必要はありません。自動解放する唯一の方法がUnmanagedを使用しているので、をnilの内容で構成することは、Swiftでは難しくありません。あなたの更新への対応

...

objc_getClassList関数のシグネチャはスウィフトの自動Cのインポートでグリッチです。間違って、Class *パラメータをAutoreleasingUnsafeMutablePointer<AnyObject?>としてインポートする必要があります。あなたは本当にあなたが配列から得ることができますUnsafeMutablePointerが必要になります。

var allClasses = Array<AnyClass?>(count: Int(objc_getClassList(nil, 0)), repeatedValue: nil) 
allClasses.withUnsafeMutableBufferPointer { (inout bp: UnsafeMutableBufferPointer<AnyClass?>) in 
    objc_getClassList(AutoreleasingUnsafeMutablePointer(bp.baseAddress), Int32(allClasses.count)) 
} 
+1

"Swiftであなた自身が決して' AutoreleasingUnsafeMutablePointer'を入力しないで問題を避けてください。 'objc_getClassList'を呼び出すなど、Objective-Cランタイムを呼び出す場合はどうでしょうか?これには 'UnsafeMutablePointer 'ではなく 'AutoreleasingUnsafeMutablePointer 'ポインタが必要です。 – JAL

+0

私は実際に 'AutoreleasingUnsafeMutablePointer'を使う例を含むように質問を更新しました。おそらく、このタイプのポインターが必要ない最適化を見つけることができます。 – JAL

+1

ああ。これはヘッダーのインポートが悪いことです。私は私の答えを修正しました。 –

関連する問題