Wednesday, October 5, 2016

Caveat Formatter

Jeff Johnson:

However, if you attempt to return the original string by reference, it doesn’t work right. The new, invalid string will still appear in the text field, despite the fact that -isPartialStringValid: returns NO. By experimentation — computer science! — I discovered that you have to provide a reference to a copy of the original string rather than the original string itself. This is probably some kind of bug in AppKit.

This does seem to be consistent with the documentation:

In a subclass implementation, evaluate partialString according to the context. Return YES if partialStringPtr is acceptable and NO if partialStringPtr is unacceptable. If you return NO and assign a new string to partialStringPtr and a new range to proposedSelRangePtr, the string and selection range are changed, otherwise, if no values are assigned to partialStringPtr or proposedSelRangePtr, the change is rejected. If you return NO, you can also return by indirection an NSString object (in error) that explains the reason why the validation failed; the delegate (if any) of the NSControl object managing the cell can then respond to the failure in control:didFailToValidatePartialString:errorDescription:.

But it’s probably not what you would expect.

2 Comments RSS · Twitter

Hi. Thanks for the plug!

I'm not sure how this is consistent with the documentation though? We're returning NO, so there are two possibilities. (1) "If you return NO and assign a new string to partialStringPtr and a new range to proposedSelRangePtr, the string and selection range are changed". In other words, the string value of the control is changed to your new partialStringPtr assignment. But if you assign partialStringPtr to the original string value of the control, before the typing, then the control should go back to its original value. (2) "otherwise, if no values are assigned to partialStringPtr or proposedSelRangePtr, the change is rejected". In other words, the control goes back to its original string value. So in either scenario, the invalid partial string should not appear in the control.

Or maybe you're suggesting there's an unspecified third scenario, distinct from (1): you return NO and assign the original string to partialStringPtr? So it's consistent simply in the sense of being undefined behavior?

@Jeff Yeah, I think if you go by what it actually says (though they don’t define “a new string”) what you were doing is undefined. My guess is that the intended behavior is what you expected and the documentation is accidentally consistent with the implementation. Anyway, thanks for noting this subtlety.

Leave a Comment