Question

This is a Q&A to hopefully help anyone else who runs into this issue. The problem occurred seemingly at random while I was working on transferring the FirstResponder chain between controls.

The controls were custom control objects inherited from UIView with either a UITextField or UITextView added as a subview (with other controls) and generated entirely in code.

Not every instance of the controls that were generated threw the exception, but the ones that did did so consistently whether the textfield/textview had [text becomeFirstResponder] called in code, OR the textfield/textview was tapped on.

I was tearing my hair out for about 6 hours on this one...

Was it helpful?

Solution

The base custom control had a boolean value 'firstResponder' which I was using to keep track of which of the custom controls on a screen should start editing first.

In the initialisation code was the following:

if([firstResponderAttribute isEqualToString:@"YES"]) firstResponder=YES; else firstResponder=NO;

When the firstResponderAttribute was YES the control threw the error, when it was NO the control was fine. Evidently when setting 'firstResponder' to NO (==0x0) the responder chain was seeing the value as nil, but when it was set to YES (==0x1 from the error message) the responder chain was trying to access an object at address 0x1 and failing.

Solution? Don't use firstResponder as value in any UIView subclass!

On a side note this problem wasn't picked up by Analyse and I haven't found any reference to the value in Apple docs (although I haven't looked very hard...)

OTHER TIPS

I got this crash when the UITextField delegate was nil. Make sure for example the delegate is not set to "File's Owner" in a NIB file where that field is nil.

Sometimes, when view on the bottom or view not on screen/superview now you get

EXC_BAD_ACCESS
/* when you try*/
[responder becomeFirstResponder]
/*or*/
[super becomeFirstResponder];

just try do it later. For example (do it when view/view_with_responder on the screen:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [_toTokenField becomeFirstResponder];
        });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top