I'm using a NSTextField which I have bound to an integer via a binding in the storyboard. The Swift code looks like this:
@objc dynamic var quantity: Int = 0
This works great for validating numbers and I get a helpful message if there is an attempt to enter something invalid, for example alphabetic letters.
The problem I'm having is that the application is crashing when you tab out of the field without filling anything in. Following the error messages, the most relevant appears to be:
2019-03-09 16:29:46.813928+0000 ViewWebSocketLearning[34535:1969855] [General] [<ViewWebSocketLearning.OrderFormViewController 0x103131820> setNilValueForKey]: could not set nil as the value for the key show.
2019-03-09 16:29:46.825146+0000 ViewWebSocketLearning[34535:1969855] [General] (
0 CoreFoundation 0x00007fff3d7b6ded __exceptionPreprocess + 256
1 libobjc.A.dylib 0x00007fff69882720 objc_exception_throw + 48
2 CoreFoundation 0x00007fff3d7b6c1f +[NSException raise:format:] + 201
3 Foundation 0x00007fff3fbe8dbb -[NSObject(NSKeyValueCoding) setNilValueForKey:] + 81
4 Foundation 0x00007fff3fac1450 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 331
5 Foundation 0x00007fff3faec38a -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 271
6 AppKit 0x00007fff3af0bf03 -[NSBinder _setValue:forKeyPath:ofObject:mode:validateImmediately:raisesForNotApplicableKeys:error:] + 473
7 AppKit 0x00007fff3af0bccf -[NSBinder setValue:forBinding:error:] + 236
8 AppKit 0x00007fff3b54c376 -[NSValueBinder _applyObjectValue:forBinding:canRecoverFromErrors:handleErrors:typeOfAlert:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert:] + 225
9 AppKit 0x00007fff3b54c698 -[NSValueBinder applyDisplayedValueHandleErrors:typeOfAlert:canRecoverFromErrors:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert:error:] + 544
10 AppKit 0x00007fff3b54c81a -[NSValueBinder _applyDisplayedValueIfHasUncommittedChangesWithHandleErrors:typeOfAlert:discardEditingCallback:otherCallback:callbackContextInfo:didRunAlert:error:] + 105
11 AppKit 0x00007fff3b053e4e -[NSValueBinder validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:] + 460
12 AppKit 0x00007fff3b053c5a -[_NSBindingAdaptor _validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:bindingAdaptor:] + 175
13 AppKit 0x00007fff3b053b8d -[_NSBindingAdaptor validateAndCommitValueInEditor:editingIsEnding:errorUserInterfaceHandled:] + 240
14 AppKit 0x00007fff3af83e2b -[NSTextField textShouldEndEditing:] + 368
15 AppKit 0x00007fff3af44cc9 -[NSTextView(NSSharing) resignFirstResponder] + 499
16 AppKit 0x00007fff3ada2522 -[NSWindow _realMakeFirstResponder:] + 258
17 AppKit 0x00007fff3b058001 -[NSTextView(NSPrivate) _giveUpFirstResponder:] + 263
I am interpreting this as the NSTextField binding not accepting a nil entry, apparently caused by leaving the field blank.
How can I prevent this exception from occurring? For my application, it's perfectly fine to leave the field blank while working on something else.
By using NSTextFields with bindings Cocoa uses the key-value coding methods (KVC) such as setValue:forKey:
Bindings setup in Storyboard/XIB are always tied to NSObject subclass object (controller). Non-object values are handled specially:
If your key-value coding compliant object receives a
setValue:forKey:
message with nil passed as the value for a non-object property, the default implementation has no appropriate, generalized course of action. It therefore sends itself a setNilValueForKey: message, which you can override. The default implementation ofsetNilValueForKey:
raises anNSInvalidArgumentException
exception, but you can provide an appropriate, implementation-specific behavior.
In your case OrderFormViewController
didn't have overriden setNilValueForKey: method and it thrown exception.
Implementing setNilValueForKey
: will solve all the issues.
PS: Using NSNumberFormatter or binding to a NSNumber object would solve the issue as well.