Reputation: 1011
I'm trying to do something very simple in a Mac app, with a frustrating problem.
I have a NSPopUpButton with 5 items, a NSTextView, and a NSMutableArray with five strings. When the popupbutton selection is changed, the corresponding string is displayed in the text view. When the text view text changes, the corresponding string in the array is also changed.
Some code:
In init code:
self.array = [NSMutableArray arrayWithObjects:@"string 1", @"string 2", @"string 3", @"string 4", @"string 5", nil];
In view body:
-(void)popUpChanged:(id)sender {
NSInteger index = [sender indexOfSelectedItem];
NSString *string = [self.array objectAtIndex:index];
self.textView.string = string;
NSLog(@"Selected string: %@", string);
}
-(void)textDidChange:(NSNotification *)notification {
NSInteger selectedSegment = self.popUp.indexOfSelectedItem;
NSText *newText = notification.object;
[self.array replaceObjectAtIndex:selectedSegment withObject:newText.string];
NSLog(@"New string: %@", newText.string);
}
Problem: PopUp item 0 is selected, "string 1" is displayed in textView.
TextView is changed to "string 100"
PopUp item 4 is selected, "string 5" is displayed in textView.
PopUp item 0 is selected again. TextView shows "string 5", but should show "string 100".
(NSLogs show that the string is correctly changed in textDidChange:
but that it has been changed to "string 5" in popUpChanged:
)
What is going on?
Upvotes: 0
Views: 61
Reputation: 53010
The documentation of NSText
's string
method states (emphasis added):
For performance reasons, this method returns the current backing store of the text object. If you want to maintain a snapshot of this as you manipulate the text storage, you should make a copy of the appropriate substring.
Which means the object you place in your array gets constantly updated and tracks the content of the text view.
Try:
[self.array replaceObjectAtIndex:selectedSegment withObject:newText.string.copy];
Upvotes: 1