NSOutlineView意外找到零

问题描述 投票:0回答:1

我正在尝试在侧面板(带有拆分视图控制器)中打开的应用中制作一个文件浏览器

源是由上一个viewController中的prepareForSegue方法带来的URL。

每次vc加载时我都出现致命错误:

致命错误:在隐式展开一个可选值时意外发现nil

编译器将错误定位到我声明的位置:

outlineView.delegate =自我outlineView.dataSource =自我

我尝试过:1.通过代码,通过以下方式撤消和重做我所有的网点连接故事板2.通过情节提要通过代码重新连接委托和数据源3.我以为我的数据源方法可能有问题,我重写了5次4.我也尝试将setDelegatesAndDatasource方法也放入viewDidAppear中,认为这是视图生命周期的问题

我不知道发生了什么。感谢您的帮助。

'''

extension ViewControllerSource : NSOutlineViewDataSource, NSOutlineViewDelegate {   

    func setDelegatesAndDatasources(){
        outlineView.delegate = self
        outlineView.dataSource = self
    }


    // MARK: - NSOutlineView Datasource

    func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
        if let fileSystemItem = item as? FileSystemItem {
            return fileSystemItem.children.count
        }
        return 1

    }

    func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
        if let fileSystemItem = item as? FileSystemItem {
            return fileSystemItem.children[index]
        }
        return rootfileSystemItem
    }

    func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
        if let fileSystemItem = item as? FileSystemItem {
            return fileSystemItem.hasChildren()
        }
        return false
    }

    // MARK: - NSOutlineView Delegate

    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
        guard let colIdentifier = tableColumn?.identifier else { return nil }

        if colIdentifier == NSUserInterfaceItemIdentifier(rawValue: "col1") {
            let cellIdentifier = NSUserInterfaceItemIdentifier(rawValue: "cell1")
            guard let cell = outlineView.makeView(withIdentifier: cellIdentifier, owner: nil) as? NSTableCellView else { return nil }

            if let collection = item as? FileSystemItem {
                cell.textField?.stringValue = collection.name ?? "Title not available"
                cell.textField?.isEditable = false
                cell.textField?.wantsLayer = true
                cell.imageView?.image = collection.icon
                // cell.textField?.delegate = self
            } else {
                cell.textField?.stringValue = "unknown item"
                cell.textField?.isEditable = false
                cell.textField?.wantsLayer = true
            }

            return cell
        } else {
            return nil
        }
    }


}

'''

这是主要的viewController文件:

'''

class ViewControllerSource: NSViewController {

    @IBOutlet var outlineView: NSOutlineView!

    var echo:Echo? {
        didSet {
            echo!.checkFolderIntegrity()
            rootfileSystemItem = FileSystemItem(url: echo!.url)
            let window = self.view.window?.windowController as! WindowControllerEcho
            window.directoryPath.url = echo!.url
        }
    }


    let propertyKeys: [URLResourceKey] = [.localizedNameKey, .effectiveIconKey, .isDirectoryKey, .typeIdentifierKey]
    var rootfileSystemItem: FileSystemItem! {
        didSet {
            displayItems()
            outlineView.reloadData()
        }
    }


    // MARK: - Initialization

    override func viewDidLoad() {
        super.viewDidLoad()
        setDelegatesAndDatasources()
    }


    func displayItems(){
        for fileSystemItem in rootfileSystemItem.children as [FileSystemItem] {
            print("item : \(fileSystemItem)")
            for subItem in fileSystemItem.children as [FileSystemItem] {
                print("\(fileSystemItem.name) - \(subItem.name)")
            }
        }
    }
}




extension ViewControllerSource : EchoDelegate {
    func didLoad(echo: Echo) {
        self.echo = echo

    }
}

'''

swift macos nsoutlineview
1个回答
0
投票

prepareForSegue代码揭示了错误:

您正在echo中设置prepareForSegue。这导致调用属性观察器didSet。但是,此时此视图尚未加载,并强制展开类型崩溃。

解决方案是将didSet中的代码移到viewDidLoad中并删除属性观察器。尽管如此,我还是建议选择绑定window

var echo : Echo!

override func viewDidLoad() {
    super.viewDidLoad()
    setDelegatesAndDatasources()
    echo.checkFolderIntegrity()
    rootfileSystemItem = FileSystemItem(url: echo.url)
    if let window = self.view.window?.windowController as? WindowControllerEcho {
        window.directoryPath.url = echo.url
    }
}

一次设置delegatedataSource就足够了。如果您使用情节提要或Xib,最方便的方法是在Interface Builder中将两者连接。

© www.soinside.com 2019 - 2024. All rights reserved.