Swift, NSOutlineView, and EXC_BAD_ACCESS...

Hey All,

I've got a pretty basic NSOutlineView going as I try and learn AppKit and Mac dev, my "Object Value for Table Column" is giving me some headache.


    var rootURL = NSURL(fileURLWithPath: "/");
  
    var rootItem:FileSystemItem! = nil;
    convenience init(withRootURL url:NSURL)
    {
        self.init()
        self.rootURL = url;
        self.rootItem = FileSystemItem(withURL: url)
    }
  
    func outlineView(outlineView: NSOutlineView, numberOfChildrenOfItem item: AnyObject?) -> Int {
        var fileItem = item as? FileSystemItem;
        if fileItem == nil {
            fileItem = self.rootItem;
        }
        return fileItem?.numberOfChildren() ?? 1;
    }
  
    func outlineView(outlineView: NSOutlineView, isItemExpandable item: AnyObject) -> Bool {
        let fileItem = item as? FileSystemItem;
        let numChildren = fileItem?.numberOfChildren();
        return numChildren > 0 ? true : false;
    }
  
    func outlineView(outlineView: NSOutlineView, child index: Int, ofItem item: AnyObject?) -> AnyObject {
        let fileItem = item as? FileSystemItem;
        return fileItem?.childAtIndex(index) ?? self.rootItem.childAtIndex(index)!;
    }
  
    func outlineView(outlineView: NSOutlineView, objectValueForTableColumn tableColumn: NSTableColumn?, byItem item: AnyObject?) -> AnyObject? {
      
        if let theItem = item
        {
            if let fileItem = theItem as? FileSystemItem   <-----------EXC_BAD_ACCESS
            {
                return fileItem.fileURL.lastPathComponent
            }
        }
      
        return "Empty?"
    }



I've indicated above where I'm getting a BAD_ACCESS error. This usually means something that's deallocated is being referenced, but how could the item passed in by the framework be deallocated?


Now, NSOutlineViews have confused the heck out of me with how they pass "nil" in for the "items" sometimes. This definitely happens on the initial "Number of Children for Item" Check. It's assumed that an inquiry with a nil item is representative of the "root item". Is this also true for the child of item call?

Answered by J0hn in 34054022

Welp, something to try and keep in mind. I got around this by caching the child elements inside the FileSystemItem and not refreshing them. I believe I was breaking references inside NSoutlineView and it would ask me for information about deallocated objects.


It appears that the child elements need to be persisted, and not refreshed everytime "child at Index" or "Number of children" gets called on the FileSystemItem.

Accepted Answer

Welp, something to try and keep in mind. I got around this by caching the child elements inside the FileSystemItem and not refreshing them. I believe I was breaking references inside NSoutlineView and it would ask me for information about deallocated objects.


It appears that the child elements need to be persisted, and not refreshed everytime "child at Index" or "Number of children" gets called on the FileSystemItem.

Hi J0hn,


Like you, I was recently bitten by this. Eventually, I found that the documentation (specifically The Data Source and Memory Management section) does mention that you must keep a strong reference to the objects that you've previous returned to the outline view.


Unfortunately, for me, even when I notify the outline view that I want it to fetch a new object, it refuses to update its object unless I call reloadData().


Anyway, just thought I'd add my two cents in case anyone else comes along with the same problems.


Craig

Swift, NSOutlineView, and EXC_BAD_ACCESS...
 
 
Q