好的,这是我在使用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)
}XCode 7.0 (7A220)
发布于 2015-09-22 16:58:23
原因似乎是该函数返回一个可选的CFDictionary?,而不能转换为(非可选的) NSDictionary。
下面是一个简单的示例,演示了CFString与NSString的相同问题
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块。
请注意,在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
}https://stackoverflow.com/questions/32716146
复制相似问题