About Core Foudation in Working with Cocoa Data Types

( iOS )

AV Foundation関連のプログラムをSwiftで書き直しているときに、単純に変換できないところがあったので 一旦でキュメントに振り返って読み直してみました。

参照先はAppleの公式ドキュメントに記載してあるのを自分なりに翻訳してみました。

Core Foundation

Core Foundation型は自動的にfull-fledgedなSwiftクラスとしてインポートされる。 メモリ管理が提供されるときはいつでも、Swiftは自動的にCore Foundation objectsのメモリを管理し、 自身をインスタンス化したCore Foundation objectsをインクルードして管理します。Swift内で、 あなたはtoll-free bridgedFoundationCore Foundationの両方を相互に変換できる。 あなたはブリッジしているFoundation型をキャストするならSwiftの標準ライブラリに対してtoll-free bridgedCore Foundation型をブリッジすることができる

  • toll-free bridged
    • オブジェクトを変換することなくキャストすることで相互変換可能な仕組みのことを指すらしいです

Remapped Types

SwiftはCore Foundation型をインポートするとき、コンパイラはそれらの型名を再配置する コンパイラは各型の最後に記述されているRefを削除する、なぜならSwiftクラスのすべては参照型、 それゆえにサフィックスはいらない

CFTypeRefAnyObjectに再配置されるよ。CFTypeRefをつかうときはAnyObjectを利用すべきだ!

Memory Managed Objects

APIから返却されたCore Foundation objectsはSwiftで自動的にメモリ管理される。 あなたは自分自身でCFRetain、CFRelease、CFAutoreleaseを呼び出す必要はない。独自のCの関数からCore Foundation objects を返すのなら、それらをCF_RETURNS_RETAINEDCF_RETURNS_NOT_RETAINEDのいずれかを使ってアノテートする。 上記のAPIを呼び出すSwiftコードをコンパイルするとき、コンパイラは自動的ににメモリ管理用の呼び出しを行う。 Core Foundation objectsを返さないAPIを利用するときは、このセクションをスキップしてね。 でないのならunmanaged Core Foundation objectsの操作について学んでね。

Unmanaged Objects

Swiftが提供されているAPIをimportするときに、コンパイラは自動的に返却されたCore Foundation Objectsをメモリ管理できないよ SwiftはUnmanaged<T>構造体内でこれらの返却されたCore Foundation objectsを内包する 間接的に返却されたCore Foundation objectsのすべては管理されい。例えば以下のように宣言できる

Objective-C

CFStringRef StringByAddingTwoStrings(CFStringRef string1, CFStringRef string2)

Swift

func StringByAddingTwoStrings(CFString!, CFString!) -> Unmanaged<CFString>!

非管理のオブジェクトを受け取るとき、あなたは直接メモり管理されたオブジェクトに変換すべきです、非管理のオブジェクトを受け取る前に。 この方法でSwiftは手動でメモリ管理を行うことができる。 Unmanaged構造体は非管理オブジェクトをメモリ管理されたobjectにtakeUnretainedValue()に変換したり、takeRetainedValue()に変換したりと2つの方法を提供する。 あなたは自分が呼びだだしているAPIがunretained objectやretained objectを返すかどうかを基本に利用するためにどちらかのメソッドを選べる。

Swift

let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue()
// memoryManagedResult is a memory managed CFString

非管理のオブジェクトであるretain() release() autorelease() メソッドを呼び出すことができます、しかしこのアプローチは推奨されないよ

まとめ

どうもSwiftでもARC非対応のものがあるのでUnmanaged<T>構造体を利用してtakeUnretainedValue()takeRetainedValue()経由でメモリ管理されたオブジェクトにしなければならないようだ。 とはいえまだ完全理解というわけではないので引き続き調べていこうと思う。

参考文献

詳解 Objective-C 2.0 第3版
詳解 Objective-C 2.0 第3版