获取空指针异常试图从当前活动 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 方面真的很糟糕)。
问题是我得到一个异常,因为 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
}
我正在尝试确定当前的前台应用程序是否处于全屏模式(另一个应用程序)。我在谷歌上广泛搜索以找到答案,我发现了类似的 Objective-C 示例,我尽我所能将我的情况转换为 swift(我在 Objective-C 方面真的很糟糕)。
问题是我得到一个异常,因为 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
}