Thanks for the responses guys, I think I follow most of it. My documents for this app are essentially movies (4D images, the 4th dimension is time). I want this particular slider to set the timepoint for all open documents, in a 'write only' fashion. Currently there is no UI to set the timepoints individually, and each document carries internal logic to prevent setting a timepoint beyond the end of the file.
Currently I have implemented this behaviour by binding the slider to a property on my document controller, and the setter for this forwards the desired timepoint onto all open documents. I was hoping to replace this with a binding just to eliminate some glue code. I thought it would be simple because I have another slider which is bound to the 'contrast' property of the selection from the array controller, and this behaves exactly as I want it to (the selection is controlled via a table view, and the slider will set the contrast of all selected rows). I hope the above is clear. Is keeping the property on the document controller likely the simplest way forward? Toby On 21 Jan 2012, at 08:54, Ken Thomases <k...@codeweavers.com> wrote: > On Jan 21, 2012, at 1:00 AM, Quincey Morris wrote: > >> On Jan 19, 2012, at 03:03 , Tobias Wood wrote: >> >>> Binding the NSSlider's value to the NSArrayController's >>> "arrangedObjects.propertyName" causes my program to get a SIGABRT on >>> opening, with the following uncaught exception: >>> "Cannot create double from object ( ) of class __NSArray0" >>> >>> I assume this is to do with the empty array. >> >> No, it's because you can't bind through a key path that contains a >> collection property ("arrangedObjects" in this case). > > Not to get too deep into the weeds, but arrangedObjects is, like selection, > also a proxy and it does allow binding through it. That's a big part of its > purpose/value. > >> This situation is complicated by the fact that NSArray responds to a >> selector it doesn't recognize (such as your "propertyName") by returning the >> result of sending this selector to every element in the array. > > Um, not quite. This isn't about not responding to a selector, it's about its > implementation of -valueForKey:. NSArray implements -valueForKey: by > returning an array of the results of invoking -valueForKey: with the same key > argument on each of its elements. > >> This array result isn't convertible to the slider's numeric value by any >> standard KVC mechanism, so you get the exception. > > That's the meat of the issue. > > >>> I have tried binding the NSSlider's enable to "arrangedObjects.@count" and >>> "arrangedObjects.canRemove". Neither fixes the problem. If I bind the value >>> to "selection.propertyName", the enabling/disabling works as expected (i.e. >>> the slider is greyed out until the array has at least one entry). Hence I >>> am confused. >> >> There's an important difference between "selection" and "arrangedObjects". >> The latter is an array, but "selection" is a proxy object that represents >> either a single object from the controller (*the* selected object), or a >> special multiple-selection marker, or a special invalid value marker, or a >> special no-value marker. The special markers are used (for example) for >> making text fields show "multiple selection" or "no value" messages, and for >> automatically enabling/disabling controls as you noted. > > You correctly diagnosed that the exception was due to the inability to make a > double from the array. That's the whole of the necessary explanation for the > symptom. Tobias had simply made an incorrect assumption that it was due to > the array being empty, but neither that nor the no-selection marker from the > selection property are relevant. > > It is true that the automatic enabling/disabling when bound to > selection.propertyName is due to the selection's markers and the > Conditionally Sets Enabled bindings option (which is on by default). But > that doesn't resolve the confusion about why it was throwing an exception in > some cases and not others. > > >> Again, there's a complication. Table view *column* bindings are special in >> that they appear to be able to bind through collection objects, but in fact >> their key paths are treated as 2 separate parts by the bindings mechanism. >> The first part allows the column to find the array of values for all table >> rows, and to choose the correct value per row based on the row index; the >> second part allows the column to find the actual value to display. > > Table columns do have special handling for array-valued bindings. It's that > they distribute the array values among their rows. Table columns are not > special in being able to bind through collection properties. That's a > feature of NSArrayController. > > The table column's bindings still have just an observed object (often the > array controller) and a single key path (often of the form > "arrangedObject.propertyName"). It's just that, when they receive an array > from [observedObject valueForKeyPath:observedKeyPath], they know to pick one > element from that array for each row. > > >> It's not entirely clear what you mean. Are you saying you want to have a >> single slider in your window, that somehow represents all the array >> elements? If so, what value would the slider show when the array elements >> have different values for the relevant property? Is there a table view >> involved in this somewhere? > > Yes, these are the important questions. Tobias, what do you actually intend > the slider to signify? What should happen when its value is adjusted by the > user? > > Regards, > Ken > _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com