Strange behavior from custom NSFormatter object
Strange behavior from custom NSFormatter object
- Subject: Strange behavior from custom NSFormatter object
- From: Charlton Wilbur <email@hidden>
- Date: Mon, 29 Nov 2004 16:32:05 -0500
All,
I posted on this matter on the cocoadev.com wiki, but no luck so far --
if I figure it out due to help here, I'll post a followup there, and
vice versa.
I'm trying to apply a custom NSFormatter subclass to a text field.
What seems to be happening is that it functions properly -- and then,
*after* I have tabbed away from the field, it takes a value from
somewhere else. Practically speaking, this means that the model object
gets the correct value from the formatter, but the text field does not,
and so editing it is impossible.
Also, the NSFormatter is currently applied to an NSTextField. The same
NSFormatter needs to be applied to table cells eventually, but I
figured it would be easier to debug with a text field. Presumably the
NSTextField can be trusted to store an object value, if it can be
trusted to store a string value? What I expect to have happen is that
(a) when I call [attrBase setObjectValue: foo], that the string value
that the formatter returns will be displayed and made available for
editing, and that (b) when the user edits the string, it gets passed
through the formatter to return an object, which is what will be
returned from an [attrBase objectValue] message. (If anybody has reason
to believe that these beliefs are wrong, please say so!)
To isolate the problem and be sure that it wasn't something elsewhere
in the project that was causing the problem, I reimplemented just the
parts that caused me problems in a separate project, on the theory that
if it were something wrong in the nib file, it would not occur in the
new file, and then I could just try to figure out what was different. I
saw the same behavior.
Here's a log of what happens:
2004-11-29 00:53:50.182 FloatingInspector[19019] InspectorWindow got
showWindow message
2004-11-29 00:53:50.281 FloatingInspector[19019] InspectorWindow got a
notification triggering newTableRowSelected: index 0
2004-11-29 00:53:50.283 FloatingInspector[19019] AE copied
2004-11-29 00:53:50.284 FloatingInspector[19019] original (0x37d8a0): []
2004-11-29 00:53:50.285 FloatingInspector[19019] copy (0x301810): []
2004-11-29 00:53:50.286 FloatingInspector[19019]
ArithmeticExpressionFormatter (0x381d60) asked to format [] for editing
2004-11-29 00:53:50.337 FloatingInspector[19019] table view asked for
element at row 0
// here I started typing "3+2"
2004-11-29 00:53:50.350 FloatingInspector[19019] AE copied
2004-11-29 00:53:50.351 FloatingInspector[19019] original (0x301810): []
2004-11-29 00:53:50.351 FloatingInspector[19019] copy (0x3848d0): []
2004-11-29 00:53:55.655 FloatingInspector[19019]
ArithmeticExpressionFormatter (0x381d60) examined 3
2004-11-29 00:53:55.655 FloatingInspector[19019] and found it parseable
2004-11-29 00:53:55.783 FloatingInspector[19019]
ArithmeticExpressionFormatter (0x381d60) examined 3+
2004-11-29 00:53:55.784 FloatingInspector[19019] and found it
unparseable
2004-11-29 00:53:56.086 FloatingInspector[19019]
ArithmeticExpressionFormatter (0x381d60) examined 3+2
2004-11-29 00:53:56.086 FloatingInspector[19019] and found it parseable
2004-11-29 00:53:57.332 FloatingInspector[19019]
ArithmeticExpressionFormatter (0x381d60) examined 3+2
2004-11-29 00:53:57.332 FloatingInspector[19019] and found it parseable
2004-11-29 00:53:57.332 FloatingInspector[19019]
ArithmeticExpressionFormatter (0x381d60) examined 3+2
2004-11-29 00:53:57.332 FloatingInspector[19019] and found it parseable
2004-11-29 00:53:57.334 FloatingInspector[19019]
ArithmeticExpressionFormatter (0x381d60) examined 3+2
2004-11-29 00:53:57.334 FloatingInspector[19019] and found it parseable
// here I hit enter
2004-11-29 00:53:57.335 FloatingInspector[19019] AE copied
2004-11-29 00:53:57.335 FloatingInspector[19019] original (0x393780):
[3+2]
2004-11-29 00:53:57.335 FloatingInspector[19019] copy (0x393ca0): [3+2]
2004-11-29 00:53:57.335 FloatingInspector[19019]
ArithmeticExpressionFormatter (0x381d60) asked to format [3+2] for
editing
2004-11-29 00:53:57.338 FloatingInspector[19019] Got expression [3+2]
// Victory! the model object got the right expression.
// BUT -- this is the part that seems to be misbehaving:
2004-11-29 00:53:57.339 FloatingInspector[19019]
ArithmeticExpressionFormatter (0x381d60) asked to format [] for editing
2004-11-29 00:53:57.346 FloatingInspector[19019] table view asked for
element at row 0
2004-11-29 00:53:57.356 FloatingInspector[19019] AE copied
2004-11-29 00:53:57.356 FloatingInspector[19019] original (0x393ca0): []
2004-11-29 00:53:57.356 FloatingInspector[19019] copy (0x3940b0): []
// and at this point the object is right back where it started - with
the empty string!
Here are the relevant bits of code -- these are the only things that
are substantially different from the version that worked with manually
verified strings. The document window is a table with a list of things
that can be edited; when you select one, it is displayed in a floating
inspector for editing.
// From InspectorWindow.m:
- ( IBAction ) updateTextField: (id) sender
{
NSLog (@"Got expression %@", [textField objectValue]);
[currentDocument alterElementAtIndex: elementIndex
toBe: [textField objectValue]];
[[NSNotificationCenter defaultCenter]
postNotificationName: @"InspectorDidUpdateTable" object: nil];
}
- (void) newTableRowSelected: ( NSNotification *) notification
{
[self setCurrentDocument: [notification object]];
elementIndex = [[[notification userInfo]
objectForKey: @"index"] intValue];
NSLog (@"InspectorWindow got a notification triggering
newTableRowSelected: index %d", elementIndex);
[textField setObjectValue: [[self currentDocument]
elementAtElementIndex: elementIndex]];
[textField setEnabled: YES];
}
// in TableWindow.m:
- (id) tableView: ( NSTableView *) aTableView
objectValueForTableColumn: ( NSTableColumn *) aTableColumn
row: (int) rowIndex
{
NSLog (@"table view asked for element at row %d", rowIndex);
return [[[self document] elementAtElementIndex: rowIndex]
expression];
}
// The entire ArithmeticExpressionFormatter.m:
- ( NSString *) stringForObjectValue: (id) anObject
{
NSLog (@"ArithmeticExpressionFormatter (%p) asked to format %@",
self, anObject);
if ([anObject isKindOfClass: [ArithmeticExpression class]])
return [[anObject expression] copy];
else
return nil;
}
- (BOOL) getObjectValue: (id *) anObject forString:
( NSString *) string errorDescription: ( NSString **) error
{
NSLog (@"ArithmeticExpressionFormatter (%p) examined %@", self,
string);
ArithmeticExpression *ae = [[[ArithmeticExpression alloc] init]
autorelease];
if ([ae setExpression: string])
{
*anObject = ae;
NSLog (@"and found it parseable");
return YES;
}
else
{
if (error)
*error = @"Can't parse string";
NSLog (@"and found it unparseable");
return NO;
}
}
I have reasonable faith that the ArithmeticExpression? class is
operating correctly, having tested it fairly extensively separately.
The only functions which might be relevant are -(NSString*) expression,
which returns the expression entered by the user, and -(BOOL)
setExpression: (NSString *) theExpression, which attempts to parse the
string; if it succeeds, it returns YES and updates the internal data
structures, and if it fails it returns NO and leaves the internal data
structures unmodified.
Thanks for any suggestions. I'm at a loss as to why this is happening.
Charlton
--
Charlton Wilbur
email@hidden
email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden