获取空指针异常试图从当前活动 window 获取边界 swift on OSX

Getting null pointer exception trying to get bounds from current active window with swift on OSX

我正在尝试确定当前的前台应用程序是否处于全屏模式(另一个应用程序)。我在谷歌上广泛搜索以找到答案,我发现了类似的 Objective-C 示例,我尽我所能将我的情况转换为 swift(我在 Objective-C 方面真的很糟糕)。

Objective-C example

问题是我得到一个异常,因为 bounds.memory 是零。在调试器中,它在边界上显示内存指针为 0x0000000000000000。我相信这是因为某些应用程序实际上没有 window,因此无法提供任何内容。第二种理论是应用程序有多个 window,但有些是不可见的(更有可能是因为我通过 pid 检查 for-in 循环)。

所以问题是我如何识别这些未绘制的 windows 并跳过它们?

P.S.

这是我在 Whosebug 中的第一个问题,所以如果我的问题有问题,请告诉我。我会尝试相应地编辑我的问题。

// Check if fullscreen application is in foreground

func appSwitched(notification: NSNotification) {
    let pid = NSWorkspace.sharedWorkspace().frontmostApplication!.processIdentifier
    let bounds: CGRect! = windowBounds(pid)
    print(bounds.height.description)
    print(bounds.width.description)
}

// Get bounds of specified processID window
func windowBounds(pid: Int32) -> CGRect {
    var bounds: UnsafeMutablePointer<CGRect>! = UnsafeMutablePointer<CGRect>()

    let windowList: CFArrayRef = CGWindowListCopyWindowInfo(CGWindowListOption.OptionOnScreenOnly, CGWindowID())!

    for window in windowList as NSArray {

        let id = window.objectForKey(kCGWindowOwnerPID) as! NSNumber!

        if id.intValue == pid {

            if window.objectForKey(kCGWindowOwnerName as! String) != "MyAppName" {
                let success: Bool! = CGRectMakeWithDictionaryRepresentation(window.objectForKey(kCGWindowBounds) as! CFDictionary!, bounds)
                if success != nil {
                    return bounds.memory
                }

            } else { break }
        }
    }

    return CGRect()
}

通常,您的代码使用了过多的 ImplicitlyUnwrappedOptionals -- CGRect!UnsafeMutablePointer<CGRect>!NSNumber!Bool!,其中 none 似乎是必需的。 但除了 success : Bool! 可能不是你问题的原因,所以,我把其他的放在一边。 (那些可能会引起其他问题,但这种情况应该是其他问题。)

CGRectMakeWithDictionaryRepresentation的签名如下:

public func CGRectMakeWithDictionaryRepresentation(dict: CFDictionary?, _ rect: UnsafeMutablePointer<CGRect>) -> Bool

(取自生成的 header。)

  • return的值是Bool,不是Bool?,也不是Bool!,也就是说,赋值给Bool!变量时,变量总是 non-nil。您无法使用 (success) != nil.

  • 检查函数是否成功
  • 第二个参数的类型是UnsafeMutablePointer<CGRect>。当 C-function API 声明 UnsafeMutablePointer<T> 时,您应该声明一个 T 类型的变量,并将其作为 inout 参数(前缀 &)传递。

因此,您的这行代码:

    var bounds : UnsafeMutablePointer<CGRect>! = UnsafeMutablePointer<CGRect>()

需要更改为:

    var bounds: CGRect = CGRect()

这部分:

                let success : Bool! = CGRectMakeWithDictionaryRepresentation((window.objectForKey(kCGWindowBounds) as! CFDictionary!), bounds)
                if((success) != nil)
                {
                    return bounds.memory
                }

应该是这样的:

                let success = CGRectMakeWithDictionaryRepresentation((window.objectForKey(kCGWindowBounds) as! CFDictionary?), &bounds)
                if success {
                    return bounds
                }