在 Swift 中调用 CFDictionaryContainsValue()

Calling CFDictionaryContainsValue() in Swift

我有一个 Core Foundation 字典,我想在其中查找特定值。自然地,我会使用 Core Foundation 提供的 CFDictionaryContainsValue()。第一个参数是要搜索的 Core Foundation 字典,第二个参数是 UnsafePointer<Void> 类型。我在字典中寻找一个字符串,所以我尝试了这样的事情:

var deviceToFind = "disk1"
var result: kern_return_t = KERN_FAILURE
let classesToMatch = IOServiceMatching(kIOMediaClass)
let classesToMatchDict = (classesToMatch as NSDictionary) as! Dictionary<String, AnyObject>
let matchedDevices = (classesToMatchDict as NSDictionary) as CFDictionaryRef

result = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatchCFDictRef, &storageIterator);

if CFDictionaryContainsValue(matchedDevices, &deviceToFind) == true
{
    print("Found disk1")
}

但这只是在调用 CFDictionaryContainsValue() 时崩溃 (EXC_BAD_ACCESS)。根据 Apple's documentation for interacting with UnsafePointers 我正在正确构建调用,但显然存在问题,但我不确定如何让它工作。

将 CFDictionary 强制转换为 Swift 字典然后使用 Swift 基元可能会减少摩擦。

如果您需要留在 CF-land,请执行以下操作:

let value = "VALUE" as NSString
let dict = ["KEY": "VALUE"] as CFDictionary

if CFDictionaryContainsValue(dict, unsafeAddressOf(value)) {
    print("contains value")
} else {
    print("does not contain value")
}

要从 IOReg 获取 BSD 名称,您不能直接从 matchedDevices 检索值。您必须遍历 storageIterator 并分别获取 BSD 名称 属性。

var deviceToFind = "disk1"
var storageIterator = io_iterator_t()
var object : io_object_t
var result: kern_return_t = KERN_FAILURE
let classesToMatchDict = IOServiceMatching("IOMedia")

result = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatchDict, &storageIterator)

if KERN_SUCCESS == result && storageIterator != 0 {
  repeat {
    object = IOIteratorNext(storageIterator)
    if let data = IORegistryEntryCreateCFProperty(object, kIOBSDNameKey, kCFAllocatorDefault, 0), disk = data.takeRetainedValue() as? String {
      if deviceToFind == disk {
        print("Found \(deviceToFind)")
        break
      }
    }
  } while object != 0
  IOObjectRelease(storageIterator)
}