我把一些函数返回CFArray
的CFStringRef
值.我需要从他们那里得到utf字符串.由于我不想让我的代码太复杂,我做了以下事情:
let initString = "\(TISCreateInputSourceList(nil, false).takeUnretainedValue())"
然后我只是用\n
s 分割得到的字符串以获得一个Swift字符串数组.但是,当函数开始返回非ascii字符串时,启动了麻烦.我开始得到像"\ U2345\U2344"这样的字符串.
然后我尝试接受CFArray并迭代它获取值并可能将它们转换为字符串,但我无法从中获取值:
let ar = TISCreateInputSourceList(nil, true).takeUnretainedValue() for i in 0...CFArrayGetCount(ar) - 1 { print(">> ( CFArrayGetValueAtIndex(ar, i).memory )") }
值始终为空.
我怎样才能得到实际值?
这里有一些问题.首先,TISCreateInputSourceList()
其名称中有"创建",这意味着它返回一个(+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
其具有被转换成适当的类型(这是一个对象的指针)CFStringRef
的
kTISPropertyInputSourceID
属性).不幸的是,这有点复杂(比较如何在swift中将self转换为UnsafeMutablePointer
let val = Unmanaged.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
同样,我们可以采取免费桥接的优势,现在
CFStringRef
要NSString
和String
:
let val = Unmanaged.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.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue() as String print(val) }