我调用了一些返回 CFStringRef
值的 CFArray
的函数。我需要从他们那里得到 utf 字符串。因为我不想让我的代码太复杂,所以我做了以下事情:
let initString = "\(TISCreateInputSourceList(nil, false).takeUnretainedValue())"
然后我将生成的字符串拆分为 \n
以获取 Swift 字符串数组。然而,当函数开始返回非 ascii 字符串时,麻烦就开始了。我开始收到像“\U2345\U2344”这样的字符串。
然后我尝试获取 CFArray 并对其进行迭代以获取值并可能将它们转换为字符串,但我无法从中获取值:
let ar = TISCreateInputSourceList(nil, true).takeUnretainedValue()
for i in 0...CFArrayGetCount(ar) - 1 {
print(">> ( CFArrayGetValueAtIndex(ar, i).memory )")
}
值始终为空。
如何获取实际值?
最佳答案
这里有一些问题。一、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
属性(property))。不幸的是,这有点
复杂(比较 How to cast self to UnsafeMutablePointer<Void> type in swift ):
let val = Unmanaged<CFString>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
我们可以再次利用免费桥接,现在从
kTISPropertyInputSourceID
至 CFStringRef
和 NSString
:
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)
}
关于string - Swift:CFArray:获取值作为 UTF 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34120142/