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

Reply via email to