5

これはCGImageSourceを使って作業するときに起こりましたが、CFDictionaryとNSDictionaryの間のフリーダイヤルが特定のケース。私は私が何を意味するかを示すために以下の例を構築するために管理している:CFDictionaryはNSDictionary(Swift 2.0/iOS9)に橋渡ししません

func optionalProblemDictionary() -> CFDictionary? { 
    let key = "key" 
    let value = "value" 
    var keyCallBacks = CFDictionaryKeyCallBacks() 
    var valueCallBacks = CFDictionaryValueCallBacks() 

    let cfDictionary = CFDictionaryCreate(kCFAllocatorDefault, UnsafeMutablePointer(unsafeAddressOf(key)), UnsafeMutablePointer(unsafeAddressOf(value)), 1, &keyCallBacks, &valueCallBacks) 
    return cfDictionary 
} 

かなり簡単(と少し愚かな)が、戻って、その機能とオプションのCFDictionary。この関数からNSDictionaryを作成しようとすると「楽しい」が始まります:

なぜ次のようなことはできませんか?

if let problemDictionary = optionalProblemDictionary() as? NSDictionary { 
    print(problemDictionary) // never enters, no warnings, compiles just fine 
} 

これは正常に機能しますか?

if let cfDictionary = optionalProblemDictionary() { 
    let problemDictionary = cfDictionary as NSDictionary 
    print(problemDictionary) 
} 

XCodeの7.0(7A220)

答えて

5

理由は、関数が CFDictionary?オプションを返し、それが NSDictionary(非別売)にキャストすることができないことのようです。ここで

NSStringCFStringと同じ問題を実証する単純な例です:

let cfString = "foobar" as CFString? 

if let s1 = cfString as? NSString { 
    print("s1 = \(s1)") // not executed 
} 

(質問は、このオプションのキャストが ことができるので、なぜこれがコンパイラエラーまたは 少なくともコンパイラの警告を与えるものではありません残っています決して成功しない

しかし、オプションのNSString?作品にキャスティング:。

をあなたはその後、

if let problemDictionary = cfDict as NSDictionary? { 
    print(problemDictionary) 
} 

かのブロックが実行されると、「問題のあるケースを」変更した場合、あなたの場合は

if let s2 = cfString as NSString? { 
    print("s2 = \(s2)") // prints "s2 = foobar" 
} 

、。


スウィフトにCFDictionaryを構築するためにあなたの方法は を修正し、実際に私のテストでプログラムがクラッシュを引き起こしていないことに注意してください。 1つの理由は、 辞書のコールバックが空の構造に設定されていることです。 unsafeAddressOf(key)は、Swift 文字列をNSStringに橋渡しします。すぐに割り当て解除することができます。

私は最善の方法は、スウィフト、 でCFDictionaryを構築することであるかわからないが、これは私のテストで働いていた:

func optionalProblemDictionary() -> CFDictionary? { 

    let key = "key" as NSString 
    let value = "value" as NSString 

    var keys = [ unsafeAddressOf(key) ] 
    var values = [ unsafeAddressOf(value) ] 

    var keyCallBacks = kCFTypeDictionaryKeyCallBacks 
    var valueCallBacks = kCFTypeDictionaryValueCallBacks 

    let cfDictionary = CFDictionaryCreate(kCFAllocatorDefault, &keys, &values, 1, &keyCallBacks, &valueCallBacks) 
    return cfDictionary 
} 
+0

それは質問には答えていない - NSDictionaryのに変換する方法。 –

+0

@AlexanderVolkov:私はそう思っています: 'problemDictionary = cfDictをNSDictionaryとすれば? {...} 'CFDictionaryをキャストしますか? NSDictionary?に変換し、オプションのバインディングを使用してNSDictionaryにラップします。どんな情報が欠けているのか教えてください。 –

+0

スクリーンショットをご覧ください。キャストの結果は無しです - http://www.screencast.com/t/hbjhDzCs0K –

関連する問題