2016-04-13 47 views
0

請考慮以下簡化的代碼示例。它在Swift中介紹,但在Objective-C中發生相同的行爲。將委託分配給嵌套範圍中的NSOpenPanel原因EXC_BAD_ACCESS

import Foundation 
import Cocoa 
class MainWindow : NSWindow { 
    @IBAction func onClick_openFile(sender : AnyObject?) { 
     let path = runOpenPanel(false); 
     NSLog(path as String) 
    } 

    @IBAction func onClick_crashyByeBye(sender : AnyObject?) { 
     let path = runOpenPanel(true); 
     NSLog(path as String) 
    } 

    private func runOpenPanel(useCrashyDelegate : Bool) -> NSString { 
     let openPanel = NSOpenPanel.init() 
     openPanel.canChooseDirectories = false 
     openPanel.canChooseFiles = true 
     openPanel.allowsMultipleSelection = false 

     let safeDelegate = MyOpenPanelDelegate.init() //same scope as openPanel.runModal()--works fine 
     if (useCrashyDelegate) { 
      let crashyDelegate = MyOpenPanelDelegate.init() //falls out of scope before openPanel.runModal() and crashes 
      openPanel.delegate = crashyDelegate 
     } else { 
      openPanel.delegate = safeDelegate 
     } 

     if (openPanel.runModal() == NSFileHandlingPanelOKButton && openPanel.URLs.count == 1) { 
      return openPanel.URLs[0].path! 
     } 

     return "" 
    } 
} 

class MyOpenPanelDelegate : NSObject, NSOpenSavePanelDelegate { 
    func panel(sender: AnyObject, shouldEnableURL url: NSURL) -> Bool { 
     var isDir : ObjCBool = false 
     if (NSFileManager.defaultManager().fileExistsAtPath(url.path!, isDirectory: &isDir)) { 
      return isDir || (url.path! as NSString).lastPathComponent.lowercaseString == "foo.txt" 
     } 
     return false 
    } 
} 

useCrashyDelegate參數runOpenPanel是真實的,crashyDelegate在嵌套範圍被實例化並調用openPanel.runModal()之前超出範圍。由於打開的面板將crashyDelegate分配給它的委託,我期望crashyDelegate's引用計數增加。但是,當useCrashyDelegate爲真時,應用程序會崩潰EXC_BAD_ACCESS。如果useCrashyDelegate爲假,則在與調用openPanel.runModal()相同範圍內實例化的safeDelegate被分配給打開的面板,並且沒有EXC_BAD_ACCESS

這讓我相信NSOpen P anel不會遞增其委託的引用計數。這是預期的行爲,還是這可能是一個錯誤?

回答

1

這讓我相信NSOpenPanel不會遞增其委託的引用計數。這是預期的行爲,還是這可能是一個錯誤?

它是預期的。檢查屬性的類型,你會看到它是assign(Objective-C)或unsafe(Swift),不保留強烈的參考。這是可可代表的常見設計模式。

HTH