swift - CFArray takeRetainedValue() 删除导致崩溃

标签 swift macos cocoa swift2 core-graphics

几个月来我一直在使用这段代码来查找某个事件应用程序的窗口 ID:

let info = CGWindowListCopyWindowInfo(CGWindowListOption(kCGWindowListOptionAll), CGWindowID(0)).takeRetainedValue()
            for dict in info as! [ [ String : AnyObject ] ] {
                if let windowName = dict["kCGWindowName"] as? String{
                    if(windowName == "MyWindowName"){
                        let windowID = dict["kCGWindowNumber"] as! Int
                        println("found window, window number: \(windowID)")
                        return
                    }
                }
            }

不过,在最近的 Swift 更新中,takeRetainedValue() 及其对应的 takeUnretainedValue() 似乎已被删除。我在网上找到的每篇关于它的帖子都说,只要删除调用,它就会或多或少地以相同的行为工作,但是当我这样做时,应用程序总是崩溃,并显示可爱的“Thread 1: EXC_BAD_INSTRUCTION (code=EXC_i386_INVOP, subcode= 0x0)”在“for dict in info”行上出现错误,甚至在循环开始之前。

我花了好几个小时试图解决这个问题,我找到了很多线索,但没有一个能帮到我。我收集到它与删除 takeRetainedValue() 给我留下一个非托管的 CFArray 对象有关,但我仍在学习,并且不知道在哪里从这里开始。

有什么方法可以解决我遇到的问题,如果没有,我应该完全使用另一种方法吗?

最佳答案

在 Swift 2 中访问 CoreFoundation 对象有一些有趣的变化。您不再需要从 CFArray 中获取保留或未保留的值,您可以将它直接桥接到 Swift 数组。您遇到崩溃是因为您试图在运行时将 CFArray 转换为 [[String : AnyObject]] 并且它返回 nil.

CGWindowListCopyWindowInfo 返回 CFArray?(一个可选的 CFArray)。尝试将 CFArray? 桥接至 [AnyObject] 将失败,但将其桥接至可选的 Swift 数组 ([AnyObject]?) 将有效。但是为了遍历该数组,我们必须打开它。在这里,我检查 CGWindowListCopyWindowInfo 返回的 CFArray 是否可以解包并桥接到 [AnyObject]!:

if let info = CGWindowListCopyWindowInfo(.OptionAll, CGWindowID(0)) as [AnyObject]! {
    for dict in info {
        if let windowName = dict[kCGWindowName as String] as? String {
            if (windowName == "MyWindowName"){
                let windowID = dict[kCGWindowNumber as String] as? Int
                print("found window, window number: \(windowID)")
                break
            }
        }
    }
}

如果出于某种原因 CGWindowListCopyWindowInfo 返回 nil,我们将不会尝试遍历它。

还要注意 CFString 常量 kCGWindowNamekCGWindowNumber 可以桥接到 Swift String 对象没问题.最好使用常量而不是硬编码字符串,因为常量的值可能会随时间变化。

关于swift - CFArray takeRetainedValue() 删除导致崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36140837/

相关文章:

ios - 以编程方式添加前导/顶部约束

html - Mac 上浏览器之间的字体大小不一致

cocoa - 按键时从 NSTextField 发送操作而不是返回

cocoa - NSarray 发布

cocoa-touch - Wifi与核心资料库样式同步

swift - 验证 Swift/XCTest 中方法调用的顺序

swift - 从 SharedWebCredential 获取所有登录信息

android - POSIX 级别的文件系统 API 能否在 OS X、iOS 和 Android 之间架起桥梁?

multithreading - 我是否允许在 OpenGL 2.1 的多个共享上下文中同时从同一个缓冲区对象进行渲染?

uitableview - swift 中的 TableViewCell 动画