CFArray takeRetainedValue()删除导致崩溃(CFArray takeRetainedValue() removal causing crashes)

编程入门 行业动态 更新时间:2024-10-23 10:18:18
CFArray takeRetainedValue()删除导致崩溃(CFArray takeRetainedValue() removal causing crashes)

我一直在使用这段代码来查找某个活动应用程序的窗口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()似乎已被删除。 关于它的每一篇文章,我都可以找到,只是删除调用应该让它或多或少地处理相同的行为,但是当我这样做时,应用程序总是崩溃与可爱的“线程1:EXC_BAD_INSTRUCTION(代码= EXC_i386_INVOP,子代码= 0x0)“在信息”行中的“错误”,循环甚至可以开始之前。

我花了好几个小时试图解决这个问题,而且我发现了很多线索,但没有一个人把我带到任何地方。 我已经知道它与删除takeRetainedValue()让我得到了一个非托管的CFArray对象,但是我还在学习,并且对于从这里去的地方一无所知。

有没有办法解决我遇到的问题,或者如果没有,我应该完全使用另一种方法?

I've been using this block of code to find a certain active application's window ID for months now:

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 } } }

As of a recent Swift update, however, the takeRetainedValue() and its counterpart takeUnretainedValue() have seemingly been removed. Every post about it online that I can find says just removing the call should leave it working with more or less the same behavior, but when I do, the application always crashes with the lovely "Thread 1: EXC_BAD_INSTRUCTION (code=EXC_i386_INVOP, subcode=0x0)" error on the "for dict in info" line, before the loop can even start.

I've spent hours and hours trying to solve the issue, and I've found a bunch of leads but none of them have taken my anywhere. I've gathered that it's got to do with the removal of takeRetainedValue() leaving me with an unmanaged CFArray object, but I'm still learning, and clueless as to where to go from here.

Is there any way to fix the issue I'm encountering, or if not, another approach that I should be using entirely?

最满意答案

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

CGWindowListCopyWindowInfo返回CFArray? (可选的CFArray )。 试图弥合CFArray? 到[AnyObject]会失败,但将它桥接到一个可选的Swift数组( [AnyObject]? )会起作用。 但是为了遍历那个数组,我们必须解开它。 在这里,我检查CFArray返回的CGWindowListCopyWindowInfo可以解包并桥接到[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常量kCGWindowName和kCGWindowNumber可以桥接到Swift String对象没问题。 使用常量比使用硬编码字符串更好,因为常量的值可能会随时间而变化。

There are some funky changes to accessing CoreFoundation objects in Swift 2. You no longer need to take a retained or unretained value from a CFArray, you can bridge it directly to a Swift array. You're getting a crash because you're trying to cast a CFArray to a [[String : AnyObject]] at runtime and it's returning nil.

CGWindowListCopyWindowInfo returns CFArray? (an optional CFArray). Trying to bridge CFArray? to [AnyObject] will fail, but bridging it to an optional Swift array ([AnyObject]?) will work. But in order to iterate through that array we must unwrap it. Here I check if the CFArray returned by CGWindowListCopyWindowInfo can be unwrapped and bridged to [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 } } } }

If for whatever reason CGWindowListCopyWindowInfo returns nil, we won't try to iterate through it.

Also note that the CFString constants kCGWindowName and kCGWindowNumber can be bridged to a Swift String object no problem. It's better to use the constants than hardcoded strings, as the value of the constant may change over time.

更多推荐

本文发布于:2023-04-29 11:41:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1336306.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:takeRetainedValue   CFArray   removal   crashes   causing

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!