Binding NSPopupButton crashes

  • Hi,

    I am trying to bind an NSPopupButton to the user defaults in Interface
    Builder as well as programatically binding a property in another class
    to the same user default value. The NSPopupButton is in the
    preferences window for the application.

    When I do one binding or the other, the behavior is as expected. If I
    do the IB binding, then changing the selection of the popup button
    correctly changes the user defaults. If I do the programatic binding,
    the property is set to what is in the user defaults.

    When I have both bindings and try to change the selection from the
    preferences window, my application crashes deep in binding code. No
    message is written to the console (I have -NSBindingDebugLogLevel 1
    being passed to the application).

    I assume that I am misusing bindings in some way. Any help would be
    much appreciated.

    --
    Steve Checkoway
  • > I am trying to bind an NSPopupButton to the user defaults in Interface
    > Builder as well as programatically binding a property in another class
    > to the same user default value. The NSPopupButton is in the
    > preferences window for the application.

      You're going to have to be *way* more specific. What properties of
    the button are you binding? To what controller and key? What code are
    you using when establishing the binding programatically? What does the
    stack trace look like? Are you really trying to establish the same
    binding both with Interface Builder and programmatically (or have I
    simply misunderstood)? If so, why do you feel that's necessary?

    --
    I.S.
  • I. Savant wrote:
    >> I am trying to bind an NSPopupButton to the user defaults in Interface
    >> Builder as well as programatically binding a property in another class
    >> to the same user default value. The NSPopupButton is in the
    >> preferences window for the application.
    >
    > You're going to have to be *way* more specific. What properties of
    > the button are you binding? To what controller and key? What code are
    > you using when establishing the binding programatically? What does the
    > stack trace look like? Are you really trying to establish the same
    > binding both with Interface Builder and programmatically (or have I
    > simply misunderstood)? If so, why do you feel that's necessary?

    I've noticed that too specific gets no responses on this list. See my
    previous unanswered query, for an example. =) That said, here's some
    more information.

    The part of my text you quoted says that I'm binding a property in
    another class to the user default value, so no, I'm not doing the same
    binding in both IB and programatically.

    In IB, I'm binding the selected value of the popup button to the shared
    user defaults controller with the key path "values.foo".

    Programatically, I have the following.

    NSUserDefaultsController *defaultsController = [NSUserDefaultsController
    sharedUserDefaultsController];

    [object bind:@"foo"
        toObject:defaultsController
      withKeyPath:@"values.foo"
          options:nil];

    I'm afraid I can't give you the stack trace right now because that
    computer is sleeping and I don't have the time to recreate it this
    moment, but if you really think it'd be useful, I can do it when I go
    home in the evening.

    --
    Steve Checkoway
  • On Mon, 15 Oct 2007 11:17:19 -0700, Steve Checkoway <s...> said:
    >>> I am trying to bind an NSPopupButton to the user defaults in Interface
    >>> Builder as well as programatically binding a property in another class
    >>> to the same user default value.

    You're trying to bind *what* about the NSPopupButton? Remember, lots of
    things about a popup button are bindable; and three things about a popup
    button are usually bound if you're going to bind any of them.

    I suspect (though this is just a guess, because you have not given any
    information) that what you are thinking of binding is the selectionIndexes
    (i.e. you want user defaults to preserve a knowledge of what the user has
    selected in the popup menu). But if that is all you are binding, then you
    must do it after the popup button's menu is populated or you'll crash.
    Furthermore, selectionIndexes is a set, whereas what you want to store in
    user defaults is probably a number. It might be better to do this binding in
    code, because then you can be in charge when the binding goes into effect,
    and you can use a value transformer to mediate the between the set and the
    number.

    >
    > Programatically, I have the following.
    >
    > NSUserDefaultsController *defaultsController = [NSUserDefaultsController
    > sharedUserDefaultsController];
    >
    > [object bind:@"foo"
    > toObject:defaultsController
    > withKeyPath:@"values.foo"
    > options:nil];

    But that is completely uninformative, since we don't know what values.foo
    is. What kind of value is it, and how are you binding from the popup button
    to that value?

    m.

    --
    matt neuburg, phd = <matt...>, <http://www.tidbits.com/matt/>
    A fool + a tool + an autorelease pool = cool!
    One of the 2007 MacTech Top 25: <http://tinyurl.com/2rh4pf>
    AppleScript: the Definitive Guide - Second Edition!
    <http://www.amazon.com/gp/product/0596102119>
  • Matt Neuburg wrote:
    > On Mon, 15 Oct 2007 11:17:19 -0700, Steve Checkoway <s...> said:
    >>>> I am trying to bind an NSPopupButton to the user defaults in Interface
    >>>> Builder as well as programatically binding a property in another class
    >>>> to the same user default value.
    >
    > You're trying to bind *what* about the NSPopupButton? Remember, lots of
    > things about a popup button are bindable; and three things about a popup
    > button are usually bound if you're going to bind any of them.
    >
    > I suspect (though this is just a guess, because you have not given any
    > information) that what you are thinking of binding is the selectionIndexes

    I said what I was binding in the email you quoted. "In IB, I'm binding
    the selected value of the popup button to the shared user defaults
    controller with the key path "values.foo"." It's the selected value.

    > (i.e. you want user defaults to preserve a knowledge of what the user has
    > selected in the popup menu). But if that is all you are binding, then you
    > must do it after the popup button's menu is populated or you'll crash.
    > Furthermore, selectionIndexes is a set, whereas what you want to store in
    > user defaults is probably a number. It might be better to do this binding in
    > code, because then you can be in charge when the binding goes into effect,
    > and you can use a value transformer to mediate the between the set and the
    > number.

    No, the selected value is a string and it's being stored correctly, as
    long as I don't have the programatic binding. Originally, I was storing
    an integer and I did have a value transformer to go between the string
    value and the integer. It worked fine except when I had the two bindings
    in which case I got the same crash so I changed everything to be a
    string in order to debug without the value transformer.

    >
    >> Programatically, I have the following.
    >>

    > But that is completely uninformative, since we don't know what values.foo
    > is. What kind of value is it, and how are you binding from the popup button
    > to that value?

    values.foo is a string. I'm binding it using interface builder by
    checking the selected value binding box, choosing the shared user
    defaults controller, and setting the path to values.foo.

    This part is working by itself. When I change the selection, the value
    of the selection (i.e., the string) gets written to the user defaults
    which I can see using defaults(1).

    It's only when I have the programatic binding as well that it crashes.

    --
    Steve Checkoway
  • On Oct 15, 2007, at 10:21 AM, I. Savant wrote:

    > What does the stack trace look like?

    #0    0xfffeff20 in objc_msgSend_rtp
    #1    0x9249aba4 in -[NSObject(NSKeyValueObservingPrivate)
    _notifyObserversForKeyPath:change:]
    #2    0x92e5c5c0 in -[NSController _notifyObserversForKeyPath:change:]
    #3    0x9304276c in -[NSController
    observeValueForKeyPath:ofObject:change:context:]
    #4    0x933f4fd8 in -[NSUserDefaultsController _setSingleValue:forKey:]
    #5    0x9251b2e4 in -[NSObject(NSKeyValueCoding) setValue:forKeyPath:]
    #6    0x930cbc04 in -[NSBinder
    _setValue:forKeyPath:ofObject:mode:validateImmediately:raisesForNotApplicableKeys:error
    :]
    #7    0x930cb9d4 in -[NSBinder setValue:forBinding:error:]
    #8    0x930cb68c in -[NSValueBinder
    _applyObjectValue:forBinding:canRecoverFromErrors:handleErrors:typeOfAlert:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert
    :]
    #9    0x930cb2ec in -[NSValueBinder
    applyDisplayedValueHandleErrors:typeOfAlert:canRecoverFromErrors:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert
    :]
    #10    0x930caf84 in -[NSValueBinder performAction:]
    #11    0x930cae60 in -[_NSBindingAdaptor
    _objectDidTriggerAction:bindingAdaptor:]
    #12    0x92f2e674 in -[NSControl sendAction:to:]
    #13    0x92f2e764 in -[NSApplication sendAction:to:from:]
    #14    0x92fc9e40 in -[NSMenu performActionForItemAtIndex:]
    #15    0x92fc9b70 in -[NSCarbonMenuImpl
    performActionWithHighlightingForItemAtIndex:]
    #16    0x92fab344 in AppKitMenuEventHandler
    #17    0x909dd08c in DispatchEventToHandlers
    #18    0x909dc224 in SendEventToEventTargetInternal
    #19    0x909f8a84 in SendEventToEventTarget
    #20    0x90a2eb7c in SendHICommandEvent
    #21    0x90a550e8 in SendMenuItemSelectedEvent
    #22    0x90a54fec in FinishMenuSelection
    #23    0x90aa7338 in PopUpMenuSelectCore
    #24    0x90aa6d0c in _HandlePopUpMenuSelection7
    #25    0x930804c0 in _NSPopUpCarbonMenu3
    #26    0x930b4860 in -[NSCarbonMenuImpl
    popUpMenu:atLocation:width:forView:withSelectedItem:withFont:withFlags:withOptions
    :]
    #27    0x930b3c50 in -[NSPopUpButtonCell
    trackMouse:inRect:ofView:untilMouseUp:]
    #28    0x92f2ce24 in -[NSControl mouseDown:]
    #29    0x92f2b860 in -[NSWindow sendEvent:]
    #30    0x92efeb4c in -[NSApplication sendEvent:]
    #31    0x92e6c83c in -[NSApplication run]
    #32    0x92e3d35c in NSApplicationMain
    #33    0x00002c54 in main at main.m:13

    As you can see, not a bit of it was in code that I wrote. It's very
    frustrating trying to debug something like this. Are there general
    tips to debugging bindings?

    --
    Steve Checkoway
  • On Oct 16, 2007, at 3:00 AM, Steve Checkoway wrote:

    >
    > On Oct 15, 2007, at 10:21 AM, I. Savant wrote:
    >
    >> What does the stack trace look like?

    > [stack snipped]

    Of course, as soon as I sent this, I opened up IB and figured I'd give
    it one more go before bed. I removed all bindings for that window, put
    them all back (all two of them) and everything worked. I don't know
    what to say, I must have made a mistake and redoing the bindings
    corrected it. Of course, my previous binding problem went away on its
    own for a while and then came back.

    I appreciate all the help you guys gave me. Thank you.

    --
    Steve Checkoway
previous month october 2007 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Go to today