这里有一些问题。首先,TISCreateInputSourceList()
名称中有“Create”,这意味着它返回一个 (+1) 保留
对象,您必须使用takeRetainedValue() 获取值,
不要takeUnretainedValue(),否则代码会泄漏内存:
let srcs = TISCreateInputSourceList(nil, true).takeRetainedValue()
您现在可以使用CFArray... 方法从数组中获取值,
但将其转换为NSArray(即“免费桥接”)要容易得多:
let srcs = TISCreateInputSourceList(nil, true).takeRetainedValue() as NSArray
这不是 CFStringRef 值的数组,而是
TISInputSource 对象。您可以将 NSArray 转换为 Swift 数组:
let srcs = TISCreateInputSourceList(nil, true).takeRetainedValue()
as NSArray as! [TISInputSource]
强制转换 as! 在这里是可以接受的,因为函数是
记录返回输入源数组。
现在您可以简单地遍历数组的元素:
for src in srcs {
// do something with `src` (which is a `TISInputSource`)
}
使用TISGetInputSourceProperty() 函数检索输入源的属性,例如:
let ptr = TISGetInputSourceProperty(src, kTISPropertyInputSourceID)
这会返回一个“空指针”(UnsafeMutablePointer<Void>),它必须被转换为一个对象
适当类型的指针(CFStringRef
kTISPropertyInputSourceID 财产)。不幸的是,这有点
复杂(比较How to cast self to UnsafeMutablePointer<Void> type in swift):
let val = Unmanaged<CFString>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
我们可以再次利用免费桥接,现在从
CFStringRef 到 NSString 和 String:
let val = Unmanaged<CFString>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
as String
把它们放在一起:
let srcs = TISCreateInputSourceList(nil, true).takeRetainedValue()
as NSArray as! [TISInputSource]
for src in srcs {
let ptr = TISGetInputSourceProperty(src, kTISPropertyInputSourceID)
let val = Unmanaged<CFString>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
as String
print(val)
}