※以下の情報は2014/12/19現在のものです。Swiftは言語仕様の変化が激しいので予期せず変更されている場合があります、ご了承ください。
1. ARCに管理されていないObjective-Cオブジェクトを扱う
例えばKeychainを扱うAPIなどで、ARCに管理されていないObjective-Cオブジェクトを扱うことがあります。このような場合にはUnmanaged型を使用します。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var dataTypeRef :Unmanaged<AnyObject>? | |
let status: OSStatus = SecItemCopyMatching(query, &dataTypeRef) | |
if status == noErr { | |
return (dataTypeRef!.takeRetainedValue() as NSData) | |
} |
Unmanaged型はメソッド経由でretain, release, autoreleaseを行うことができるほか、takeUnretainedValue()またはtakeRetainedValue()メソッド経由でT型のSwiftオブジェクトを取り出すことができます。
2. C言語のポインタを扱う
生のC言語のポインタを扱う場合、たいていのケースではUnsafePointer型を使うようにCのAPIがSwiftのAPIに変換されます。このとき、Swift上ではUnsafePointer型を要求するのに、C言語のAPI的にはNULLを渡したい場合には、nilを渡すことができないので、代わりにUnsafePointer.null()を渡すことができます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var nextResponse = some_api(param) | |
while (UnsafePointer<Int8>.null != nextResponse) { | |
// do something with response, then | |
nextResponse = some_api(param) | |
} |
UnsafePointer以外にもCOpaquePointer型やCFunctionPointer型に変換されるAPIもありますが、この場合も同様にCOpaquePointer.null()やCFunctionPointer.null()をAPIに渡してやればうまくいきます。
3. cStringUsingEncoding()メソッドの罠に注意する
SwiftにはSwiftネイティブのString型とCocoaのNSString型が存在します。基本的にはこの2つは自動的にうまい具合にブリッジされるためプログラマは違いを意識する必要がありませんが、実はcStringUsingEncoding()メソッドを使う場合にはこれが重大な問題になってきます。String.cStringUsingEncoding()は[CChar]?を、NSString.cStringUsingEncoding()はUnsafePointerを返すのです。さらにコンパイラは文字列をStringとして解釈するのを優先するため、先ほど述べたC言語のAPIに渡す際に型が合わないという理由でエラーになりがちです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if let value: NSString = self.filterSender { // Casted to NSString | |
let sender = value.cStringUsingEncoding(NSUTF8StringEncoding) // NSString.cStringUsingEncoding() | |
asl_set_query(query, ASL_KEY_SENDER, sender, UInt32(ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_SUBSTRING)) | |
} |
対策として上記の通り明示的にNSStringにキャストすることをおすすめします。
4. enum値のOR結合を何とかする
すみません、なんともなりませんでした(´・_・`)
例えば以下のようなコードを書くこと自体は可能なのですが、適切なenum値を得ることができません。optionsはnilになってしまいます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let options = NSStringDrawingOptions(rawValue: | |
NSStringDrawingOptions.UsesLineFragmentOrigin.rawValue | NSStringDrawingOptions.UsesFontLeading.rawValue | |
) |
どうしてもOR結合が必要なenum値が存在する場合は、現状C/Objective-Cでラッパーを作りObjective-C Bridging Header経由でSwiftから呼び出すしかないようです。