swift - CFDictionary 不会桥接到 NSDictionary (Swift 2.0/iOS9)

标签 swift nsdictionary swift2 toll-free-bridging cfdictionary

好的,这是我在使用 CGImageSource 时遇到的一个案例,我注意到 CFDictionary 和 NSDictionary 之间的免费桥接在某些情况下似乎会遇到问题。我已经设法构建了以下示例来说明我的意思:

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)
}

X代码 7.0 (7A220)

最佳答案

原因似乎是该函数返回一个可选 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)
}

然后执行 if block 。


请注意,您在 Swift 中构建 CFDictionary 的方法不正确 实际上在我的测试中导致了程序崩溃。一个原因是 字典回调设置为空结构。 另一个问题是 unsafeAddressOf(key) 桥接了 Swift 字符串到可以立即释放的 NSString

我不知道在 Swift 中构建 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
}

关于swift - CFDictionary 不会桥接到 NSDictionary (Swift 2.0/iOS9),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32716146/

相关文章:

ios - 快速将文本添加到图像中的一个点

ios - 使用 NSlocalizedstring 翻译一个 NSdictionnary 数组

ios - NSDictionary 序列化为 NSString

arrays - Swift - 从数组中修剪元素,将整数字符串转换为整数

ios - 相同的表达式在 Objective-C 和 Swift 中返回不同的值

swift - 使用 Swift 和 Codeable 处理动态值类型

ios - iOS 模拟器和真实设备的奇怪行为(联系人+nsdictionary)

ios - 在 Firebase 中保存数组

json - Swift 2.0 JSON 字符串到 JSON

ios - 从 Swift 2.3 (xCode 7) 迁移 --> Swift 4(xCode 9) + 更新 Cocoapods