2015-09-22 12 views
5

ठीक नहीं होगा, यह एक मामला है जब मैं CGImageSource के साथ काम करते समय आया था और देखा कि CFDictionary और NSDictionary के बीच टोल फ्री-ब्रिजिंग कुछ मामलों में समस्याओं में भाग लेती है । मैं दिखाने के लिए मैं क्या मतलब है नीचे दिए गए उदाहरण के निर्माण के लिए प्रबंधित किया है:CFDictionary NSDictionary (स्विफ्ट 2.0/आईओएस 9)

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 में ढाला नहीं जा सकता है कि हो रहा है।

यहाँ के साथ CFStringNSString बनाम एक ही समस्या का प्रदर्शन एक सरल उदाहरण है:

let cfString = "foobar" as CFString? 

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

(प्रश्न बना रहता है क्यों यह एक संकलक त्रुटि या कम से कम एक संकलक चेतावनी दे नहीं करता है क्योंकि यह वैकल्पिक डाली कर सकते हैं सफल होने कभी नहीं)

लेकिन एक वैकल्पिक NSString? कार्यों के लिए एक कास्टिंग:।

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

आपके मामले में, यदि आप

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

फिर अगर ब्लॉक निष्पादित किया जाता है करने के लिए "समस्याग्रस्त मामले" बदल जाते हैं।


ध्यान रखें कि आपके विधि स्विफ्ट में एक CFDictionary निर्माण करने के लिए सही और वास्तव में अपने परीक्षण में कार्यक्रम दुर्घटनाओं का कारण नहीं है। एक कारण यह है कि शब्दकोश कॉलबैक खाली संरचनाओं पर सेट हैं। एक और समस्या यह है कि unsafeAddressOf(key) स्विफ्ट स्ट्रिंग को 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 –

संबंधित मुद्दे