Really weird NSTextView behaviour

  • Hello all,

    I've wasted several hours (about 4) today debugging something really
    simple and now I've found where the behavior is coming from:
    NSTextView. Let me first explain what the situation is. I have a
    table and each row basically is an object in a NSMutableArray and
    when a row is clicked the method retrieves the object for that row
    and sets the values of some NSTextFields and a NSTextView. I'm using
    the - (void)textDidChange:(NSNotification *)aNotification delegate
    method to know when the text view has changed. The method is
    implemented as shown below:

    NSLog(@"Address changed");
    NSText* t = [aNotification object];
    DALocation* loc = [self currentSelectedLocation];
    NSLog(@"Setting the address to %@", [t string]);
    [loc setLocationAddress:[t string]];
    NSLog(@"Location object is %@", loc);

    Now this works fine. I've put a breakpoint to check if the actual
    address property is modified, etc and it is ok. Now when I click
    another row the address suddenly becomes empty! And the setter for
    the address is never called (I've put a breakpoint on it). Here's my
    action method for the table:

    -(IBAction)clickedLocationsTable:(id)sender
    {
    if([self currentSelectedLocation])
    {
      NSLog(@"Clicked on a valid row");
      [self enableLocationEditboxes];
      DALocation* loc = [self currentSelectedLocation];
      NSLog(@"Current clicked location object is: %@", loc);
      [tagsLocsLocationName setStringValue:[loc name]];
      NSString* add = [loc locationAddress];
      [tagsLocsLocationView setString:add]; // !!!!!!! OFFENDER
    }
    else
      [self disableLocationEditboxes];
    }

    Stepping through that code shows that the call setString: to
    NSTextView somehow changes the location address property of the
    previous selected object (circumventing the setter in some way). Now
    I'm really puzzled - how can this method change some internal value
    of my object??? I've tried using watchpoints but I couldn't get them
    to run (the hardware rwatch and awatch commands). The normal watch
    command is pretty useless since it doesn't work out of scope. Any
    tips for unravelling this mystery are greatly appreciated.

    Regards,
    David
  • Tried -setStringValue instead?

    --
    mikey

    On 25 Oct, 2006, at 17:42, David Aames wrote:

    > Hello all,
    >
    > I've wasted several hours (about 4) today debugging something
    > really simple and now I've found where the behavior is coming from:
    > NSTextView. Let me first explain what the situation is. I have a
    > table and each row basically is an object in a NSMutableArray and
    > when a row is clicked the method retrieves the object for that row
    > and sets the values of some NSTextFields and a NSTextView. I'm
    > using the - (void)textDidChange:(NSNotification *)aNotification
    > delegate method to know when the text view has changed. The method
    > is implemented as shown below:
    >
    > NSLog(@"Address changed");
    > NSText* t = [aNotification object];
    > DALocation* loc = [self currentSelectedLocation];
    > NSLog(@"Setting the address to %@", [t string]);
    > [loc setLocationAddress:[t string]];
    > NSLog(@"Location object is %@", loc);
    >
    > Now this works fine. I've put a breakpoint to check if the actual
    > address property is modified, etc and it is ok. Now when I click
    > another row the address suddenly becomes empty! And the setter for
    > the address is never called (I've put a breakpoint on it). Here's
    > my action method for the table:
    >
    > -(IBAction)clickedLocationsTable:(id)sender
    > {
    > if([self currentSelectedLocation])
    > {
    > NSLog(@"Clicked on a valid row");
    > [self enableLocationEditboxes];
    > DALocation* loc = [self currentSelectedLocation];
    > NSLog(@"Current clicked location object is: %@", loc);
    > [tagsLocsLocationName setStringValue:[loc name]];
    > NSString* add = [loc locationAddress];
    > [tagsLocsLocationView setString:add]; // !!!!!!! OFFENDER
    > }
    > else
    > [self disableLocationEditboxes];
    > }
    >
    > Stepping through that code shows that the call setString: to
    > NSTextView somehow changes the location address property of the
    > previous selected object (circumventing the setter in some way).
    > Now I'm really puzzled - how can this method change some internal
    > value of my object??? I've tried using watchpoints but I couldn't
    > get them to run (the hardware rwatch and awatch commands). The
    > normal watch command is pretty useless since it doesn't work out of
    > scope. Any tips for unravelling this mystery are greatly appreciated.
    >
    > Regards,
    > David
    > _______________________________________________
    > Do not post admin requests to the list. They will be ignored.
    > Cocoa-dev mailing list      (<Cocoa-dev...>)
    > Help/Unsubscribe/Update your Subscription:
    > http://lists.apple.com/mailman/options/cocoa-dev/mikey-san%
    > 40bungie.org
    >
    > This email sent to <mikey-san...>
  • On 25 Oct 2006, at 22:48, Michael Watson wrote:

    > Tried -setStringValue instead?

    [... setStringValue:]: selector not recognized [self = 0x38eda0]

    >
    > --
    > mikey
    >
    > On 25 Oct, 2006, at 17:42, David Aames wrote:
    >
    >> Hello all,
    >>
    >> I've wasted several hours (about 4) today debugging something
    >> really simple and now I've found where the behavior is coming
    >> from: NSTextView. Let me first explain what the situation is. I
    >> have a table and each row basically is an object in a
    >> NSMutableArray and when a row is clicked the method retrieves the
    >> object for that row and sets the values of some NSTextFields and a
    >> NSTextView. I'm using the - (void)textDidChange:(NSNotification *)
    >> aNotification delegate method to know when the text view has
    >> changed. The method is implemented as shown below:
    >>
    >> NSLog(@"Address changed");
    >> NSText* t = [aNotification object];
    >> DALocation* loc = [self currentSelectedLocation];
    >> NSLog(@"Setting the address to %@", [t string]);
    >> [loc setLocationAddress:[t string]];
    >> NSLog(@"Location object is %@", loc);
    >>
    >> Now this works fine. I've put a breakpoint to check if the actual
    >> address property is modified, etc and it is ok. Now when I click
    >> another row the address suddenly becomes empty! And the setter for
    >> the address is never called (I've put a breakpoint on it). Here's
    >> my action method for the table:
    >>
    >> -(IBAction)clickedLocationsTable:(id)sender
    >> {
    >> if([self currentSelectedLocation])
    >> {
    >> NSLog(@"Clicked on a valid row");
    >> [self enableLocationEditboxes];
    >> DALocation* loc = [self currentSelectedLocation];
    >> NSLog(@"Current clicked location object is: %@", loc);
    >> [tagsLocsLocationName setStringValue:[loc name]];
    >> NSString* add = [loc locationAddress];
    >> [tagsLocsLocationView setString:add]; // !!!!!!! OFFENDER
    >> }
    >> else
    >> [self disableLocationEditboxes];
    >> }
    >>
    >> Stepping through that code shows that the call setString: to
    >> NSTextView somehow changes the location address property of the
    >> previous selected object (circumventing the setter in some way).
    >> Now I'm really puzzled - how can this method change some internal
    >> value of my object??? I've tried using watchpoints but I couldn't
    >> get them to run (the hardware rwatch and awatch commands). The
    >> normal watch command is pretty useless since it doesn't work out
    >> of scope. Any tips for unravelling this mystery are greatly
    >> appreciated.
    >>
    >> Regards,
    >> David
    >> _______________________________________________
    >> Do not post admin requests to the list. They will be ignored.
    >> Cocoa-dev mailing list      (<Cocoa-dev...>)
    >> Help/Unsubscribe/Update your Subscription:
    >> http://lists.apple.com/mailman/options/cocoa-dev/mikey-san%
    >> 40bungie.org
    >>
    >> This email sent to <mikey-san...>
    >
  • Oh, sorry, NSTextView, not NSTextField.

    Oops.

    --
    me

    On 25 Oct, 2006, at 17:54, David Aames wrote:

    >
    > On 25 Oct 2006, at 22:48, Michael Watson wrote:
    >
    >> Tried -setStringValue instead?
    >
    > [... setStringValue:]: selector not recognized [self = 0x38eda0]
    >
    >>
    >> --
    >> mikey
    >>
    >> On 25 Oct, 2006, at 17:42, David Aames wrote:
    >>
    >>> Hello all,
    >>>
    >>> I've wasted several hours (about 4) today debugging something
    >>> really simple and now I've found where the behavior is coming
    >>> from: NSTextView. Let me first explain what the situation is. I
    >>> have a table and each row basically is an object in a
    >>> NSMutableArray and when a row is clicked the method retrieves the
    >>> object for that row and sets the values of some NSTextFields and
    >>> a NSTextView. I'm using the - (void)textDidChange:(NSNotification
    >>> *)aNotification delegate method to know when the text view has
    >>> changed. The method is implemented as shown below:
    >>>
    >>> NSLog(@"Address changed");
    >>> NSText* t = [aNotification object];
    >>> DALocation* loc = [self currentSelectedLocation];
    >>> NSLog(@"Setting the address to %@", [t string]);
    >>> [loc setLocationAddress:[t string]];
    >>> NSLog(@"Location object is %@", loc);
    >>>
    >>> Now this works fine. I've put a breakpoint to check if the actual
    >>> address property is modified, etc and it is ok. Now when I click
    >>> another row the address suddenly becomes empty! And the setter
    >>> for the address is never called (I've put a breakpoint on it).
    >>> Here's my action method for the table:
    >>>
    >>> -(IBAction)clickedLocationsTable:(id)sender
    >>> {
    >>> if([self currentSelectedLocation])
    >>> {
    >>> NSLog(@"Clicked on a valid row");
    >>> [self enableLocationEditboxes];
    >>> DALocation* loc = [self currentSelectedLocation];
    >>> NSLog(@"Current clicked location object is: %@", loc);
    >>> [tagsLocsLocationName setStringValue:[loc name]];
    >>> NSString* add = [loc locationAddress];
    >>> [tagsLocsLocationView setString:add]; // !!!!!!! OFFENDER
    >>> }
    >>> else
    >>> [self disableLocationEditboxes];
    >>> }
    >>>
    >>> Stepping through that code shows that the call setString: to
    >>> NSTextView somehow changes the location address property of the
    >>> previous selected object (circumventing the setter in some way).
    >>> Now I'm really puzzled - how can this method change some internal
    >>> value of my object??? I've tried using watchpoints but I couldn't
    >>> get them to run (the hardware rwatch and awatch commands). The
    >>> normal watch command is pretty useless since it doesn't work out
    >>> of scope. Any tips for unravelling this mystery are greatly
    >>> appreciated.
    >>>
    >>> Regards,
    >>> David
    >>> _______________________________________________
    >>> Do not post admin requests to the list. They will be ignored.
    >>> Cocoa-dev mailing list      (<Cocoa-dev...>)
    >>> Help/Unsubscribe/Update your Subscription:
    >>> http://lists.apple.com/mailman/options/cocoa-dev/mikey-san%
    >>> 40bungie.org
    >>>
    >>> This email sent to <mikey-san...>
    >>
    >
  • On Oct 25, 2006, at 3:42 PM, David Aames wrote:

    > Now I'm really puzzled - how can this method change some internal
    > value of my object???

    I'm not sure, but did you try setting the contents of the
    NSTextStorage instead of calling -setString:?

    > I've tried using watchpoints but I couldn't get them to run (the
    > hardware rwatch and awatch commands). The normal watch command is
    > pretty useless since it doesn't work out of scope.

    Xcode's support for watchpoints is worse than useless. I just do this
    using the GDB console instead: <http://lists.apple.com/archives/xcode-
    users/2004/Oct/msg00275.html
    >

    Nick Zitzmann
    <http://www.chronosnet.com/>
  • On 25 Oct 2006, at 23:37, Nick Zitzmann wrote:

    >
    > On Oct 25, 2006, at 3:42 PM, David Aames wrote:
    >
    >> Now I'm really puzzled - how can this method change some internal
    >> value of my object???
    >
    > I'm not sure, but did you try setting the contents of the
    > NSTextStorage instead of calling -setString:?

    Yup... I've tried that and it doesn't help

    <CODE>
    NSTextStorage* ts = [tagsLocsLocationView textStorage];
    [ts replaceCharactersInRange:NSMakeRange(0, [ts length])
    withString:add];
    </CODE>

    >
    >> I've tried using watchpoints but I couldn't get them to run (the
    >> hardware rwatch and awatch commands). The normal watch command is
    >> pretty useless since it doesn't work out of scope.
    >
    > Xcode's support for watchpoints is worse than useless. I just do
    > this using the GDB console instead: <http://lists.apple.com/
    > archives/xcode-users/2004/Oct/msg00275.html>

    The post about the watchpoint was real useful... thanks for that. Now
    I've attached a watchpoint to the variable and I've discovered
    something _really_ strange: the actual NSString object doesn't change
    (it's the same pointer!) but for some reason it just reports that it
    is empty. My wildest guess would be that something is modifying the
    length of the string - so now I need to add a watchpoint for the
    count ivar of NSString (if I only knew how to do that). Also it seems
    really weird I have to resort to such extreme debug techniques to
    solve a mysterious issue... but I can't find any errors in my code.
    So thanks to anyone reading this and trying to help.

    David

    >
    > Nick Zitzmann
    > <http://www.chronosnet.com/>
    >
    >
previous month october 2006 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