2016-03-21 35 views
1

我已經使用這個代碼塊找某活動的應用程序的窗口ID幾個月以來一直是:CFArray takeRetainedValue()去除導致崩潰

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

正如最近斯威夫特更新,然而,takeRetainedValue()和其對應的takeUnretainedValue()似乎已被刪除。我可以找到的每一篇關於它的帖子都表示,只是刪除調用應該使其具有或多或少相同的行爲,但是當我這樣做時,應用程序總是與可愛的「Thread 1:EXC_BAD_INSTRUCTION(code = EXC_i386_INVOP,subcode = 0x0)「的信息字典中的」字典「錯誤,在循環甚至可以開始之前。

我花了幾個小時試圖解決這個問題,我發現了一堆線索,但他們都沒有把我帶到任何地方。我已經知道這與刪除takeRetainedValue()有關,但讓我留下一個非託管的CFArray對象,但我仍然在學習,並且對於從這裏走到哪裏毫無頭緒。

有沒有辦法解決我遇到的問題,或者如果不是,我應該完全使用另一種方法?

回答

3

訪問Swift 2中的CoreFoundation對象有一些很奇怪的變化。您不再需要從CFArray獲取保留或未保留的值,可以將其直接橋接到Swift數組。由於您試圖在運行時將CFArray轉換爲[[String : AnyObject]],並且它返回nil,所以發生崩潰。 (可選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對象沒有問題。最好使用常量而不是硬編碼的字符串,因爲常量的值可能隨時間而改變。

+0

非常感謝你的解釋和偉大的建議!現在這一切都變得更有意義了。 如何將'CFString's轉換成Swift'String's,以防止將來的更改導致問題,但是?如果值本身是可以改變的,那麼它是什麼類型的String對象又有什麼關係? –

+0

@ JackB.Cousineau在你傳遞的原始代碼中有''kCGWindowName'',它是一個字符串文字。你真正想要的是什麼(我相信)是常量['kCGWindowName'](https://developer.apple.com/library/mac/documentation/Carbon/Reference/CGWindow_Reference/#//apple_ref/doc/constant_group/Optional_Window_List_Keys) ,它指向SDK中的一些'CFString'值。如果底層字符串表示在不同的SDK版本上發生變化,Apple會爲這些值提供常量。 – JAL

+0

啊,我明白了。感謝你的幫助! –