0

I have an NSTableView in a floating window that gets dynamically bound to the arrangedObjects property of an instance of an NSArrayController that corresponds to the frontmost document window with code like the following:

NSArrayController *documentSpecificArrayController;  // properly set elsewhere
NSTableColumn *tableColumnToBind;  // properly set elsewhere

[tableColumnToBind unbind:NSValueBinding];
[tableColumnToBind bind:NSValueBinding
               toObject:documentSpecificArrayController
            withKeyPath:@"arrangedObjects"
                options:[NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES],
                         NSContinuouslyUpdatesValueBindingOption,
                         nil]];

As long as the represented array/the table view are empty, things work fine; all of the various operations on the table view/represented array within one document work fine. If one switches from a document with a non-empty represented array to a document for which the represented array is empty, an endless stream of *** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0) exceptions are thrown.

Am I missing something that I need to do in cleanly severing the binding when switching windows? Something else? (Is there some specific information that I've omitted that would help diagnose my error?)

Isaac
  • 10,668
  • 5
  • 59
  • 68
  • "properly set elsewhere" [ citation needed ] :-) – Joshua Nozzi Jan 16 '11 at 14:09
  • @Joshua Nozzi: I knew *someone* would ask. :) The array controller is a property of the document class, which is the delegate of the new topmost window, so it's gotten that way; the table column is contained in a table view that is wired to an IBOutlet of the class in which this code occurs. I have verified, independent of this exception-throwing, that both variables are set and changing as expected. – Isaac Jan 16 '11 at 16:03

1 Answers1

1

Based on your comment it seems you might be trying to create an inspector palette or something similar. Is this true? If so, you should probably just bind directly to the active document's array controller by binding to Shared Application with the key path of mainWindow.document.myArrayController. I think you're running into run loop / timing problems with Bindings and using this method should mitigate that.

Joshua Nozzi
  • 60,946
  • 14
  • 140
  • 135
  • I will test shortly, but (1) the use case is something like an inspector palette, (2) it makes sense with what I've seen thus far, and (3) it would simplify what was a rather lengthy and messy way of hooking things up down to one easy binding. Is there somewhere in the docs that I should have seen how to do this from the start? – Isaac Jan 16 '11 at 16:35
  • I don't know that this is documented specifically anywhere in Apple's stuff but it's a solution that has been floating around since the 10.3 days in various Cocoa community sites. I use it myself. Caveat: If you have different doc types and not all have that keypath, you'll need to "fill in the blanks" and return nil for the myArrayController part in the non-compliant doc classes or you'll get key path errors. – Joshua Nozzi Jan 16 '11 at 16:47
  • Additional Suggestion: Put an array controller in the palette's xib and bind the table to *it* instead. Then bind *that* array controller's content to the collection the doc's array controller is meant to represent (via the same key path "trick", just with a different final segment - the collection's key rather than the array controller's). The palette's window should own its own controllers. – Joshua Nozzi Jan 16 '11 at 16:49
  • I'm sure I'm doing something stupid, but I couldn't get this binding to work at all—the tableview in the palette never shows anything. (The controls in the palette all have identical controls in the document window bound to the same properties of the document object, so I can see what should be happening in the palette.) Beyond that, I'd expect [the issue discussed here](http://stackoverflow.com/questions/223966) where if the palette is the main window, the binding would break, but I'd think that'd be easier to work around. – Isaac Jan 16 '11 at 17:08
  • Using an separate instance of the array controller in the XIB for the palette did the trick. Thanks. – Isaac Jan 16 '11 at 17:36