0

I have character boxes made of my UINavigatableTextField. After each input, responder character should succeed to it's successor. Weirdly, during input of first character, if user enters character 'Q' each time different exception like;

  • EXC_BAD_ACCESS, or
  • 2012-09-04 14:42:42.600 Kelime Oyunu[6350:707] -[WebScriptObjectPrivate isForShortcutConversion]: unrecognized selector sent to instance 0x21b870 2012-09-04 14:42:42.606 Kelime Oyunu[6350:707] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[WebScriptObjectPrivate isForShortcutConversion]: unrecognized selector sent to instance 0x21b870'

is thrown. My code receiving exception below, the [next becomeFirstResponder] line

- (void) moveToNextCharacter: (MBNavigatableTextField *) character
{
    dispatch_async(dispatch_get_current_queue(),
               ^{
                   UIControl *next = [character nextField];

                   if(next == nil)
                   {
                       [character endEditing:YES];
                   }
                   else if ([next isKindOfClass:[UIButton class]])
                   {
                       [next sendActionsForControlEvents: UIControlEventTouchUpInside];
                   }
                   else
                   {
                       [next becomeFirstResponder];
                   }
                });
}

How can i solve the problem? Thanks in advance.

Edit 1: Found a zombie [next resignFirstResponder] (Thanks to @PhillipMills)

Edit 2: It turns out my problem caused from

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    // Something done here...

    // code block of evil zombie summoner
    [textField setText:@"Some text"];

    // Something else done here
}

Profile->Instruments->Zombies stating that during setText: some object is released (which is previous string i guess).

I am still unable to solve the problem. My goal is updating textField above with new user input (replacementString:).

Gökhan Barış Aker
  • 4,187
  • 5
  • 21
  • 35
  • I think you need to identify where things are breaking. Step through the code (or use log messages) to find the line that fails and then quote the actual error message. – Phillip Mills Sep 04 '12 at 11:27
  • @DavidH before commenting look at my other questions. If you find an answer, I will surely accept. – Gökhan Barış Aker Sep 04 '12 at 11:44
  • @PhillipMills Added log, as i said during [next becomeFirstResponder] i am receiving exc_bad_access (I checked value of next and it is not nil during execution of code line) and unknown selector (i added log details to the question with edit). – Gökhan Barış Aker Sep 04 '12 at 11:52
  • 1
    Is `isForShortcutConversion` a method in one of your classes? (If it is, try running with zombies enabled.) – Phillip Mills Sep 04 '12 at 12:00
  • @PhillipMills No it isn't one of my classes, and thanks for the tip i will inform you as soon as i get response from zombies. – Gökhan Barış Aker Sep 04 '12 at 12:01
  • 1
    A quick Google search suggests that it's a private method related to text input, so the zombies experiment may help since you're working with text fields and there's no obvious connection to `WebScriptObjectPrivate`. – Phillip Mills Sep 04 '12 at 12:07
  • @PhillipMills updated my question and yes there is a zombie but i still don't know how to fix. – Gökhan Barış Aker Sep 04 '12 at 12:22
  • 1
    Why the `dispatch_get_current_queue` ? I would rather use `dispatch_get_main_queue` for responder operations as that is related to the UI state. – A-Live Sep 04 '12 at 12:24
  • @A-Live Tried both of them still, the same result. Also you are absolutely right. It is just an artifact from the question http://stackoverflow.com/a/5889795/892500 – Gökhan Barış Aker Sep 04 '12 at 12:28
  • I downloaded the file and got 204 bytes of characters. I'm not sure if that's my problem or yours. – Phillip Mills Sep 04 '12 at 12:42
  • @PhillipMills The problem is related to zombie, great diagnostic. Your comments probably the solution. Move them to answer section and i will mark it as correct. Also a little bit background information would be awesome (i am a 3 months old iOS developer :P). thanks. – Gökhan Barış Aker Sep 04 '12 at 13:54
  • Well...I guess we're still hunting the actual problem. How is `nextfield` in `MBNavigatableTextField` declared and assigned? – Phillip Mills Sep 04 '12 at 14:36

1 Answers1

0

All messaging to UIKit objects has to be done on the main queue. While that may be the case, this statement:

dispatch_async(dispatch_get_current_queue()

is troublesome since we don't know what queue you get the message on. Change it to:

dispatch_async(dispatch_get_main_queue()

so its absolutely clear.

Also, under this line:

UIControl *next = [character nextField];

add these statements:

NSLog(@"Character CLASS %@", NSStringFromClass[character class]);
NSLog(@"next CLASS %@", NSStringFromClass[next class]);

Make sure these are what you think they should be.

EDIT: Regarding the use of "unsafe_unretained": if a IBOutlet is contained within "self.view" - that is the primary view - then you should be using weak on iOS - so it gets nil'd for you when the view goes away.

Regarding 'shouldChangeCharactersInRange', if you are simply looking at the characters, you return YES. If you change the text itself - by writing to the field/view directly, then return NO. If you modify text and then return YES, you're in essence changing data behind the control's back with who knows what consequences.

David H
  • 39,114
  • 12
  • 86
  • 125
  • Thanks. fixed dispatch_async queue to dispatch_get_main_queue(), as also suggested by @A-Live. Here my log (tried several times if it logs different results): 2012-09-04 16:43:46.179 Kelime Oyunu[4675:f803] Character CLASS MBNavigatableTextField 2012-09-04 16:43:46.180 Kelime Oyunu[4675:f803] next CLASS MBNavigatableTextField – Gökhan Barış Aker Sep 04 '12 at 13:48
  • So these messages what you expected - the class - its correct. Then when '[next becomeFirstResponder];' is sent you get a crash. You need to enable breakpoints and a break on all exceptions, and see where its crashing. Probably the last object that gets a "resign" message is causing the crash. – David H Sep 04 '12 at 14:14
  • Zombies show me some information which is below my question 'Edit 2' section. Also removing [textField setText:@"Some text"] from textField:shouldChangeCharactersInRange:replacementString: solving the problem. Still my goal is replacing each input with new one. – Gökhan Barış Aker Sep 04 '12 at 14:18
  • That's not a solution, its just avoiding the problem. So if you did that call, then either "textField was released at that point, or perhaps you didn't return NO when you set the text (which might confuse the textField, probably not but could be). All of your MBNavigatableTextFields are held in strong references? All objects they own also? – David H Sep 04 '12 at 15:00
  • yes you are right, thats just avoiding the problem. Still closest thing to solution and you quite scared me at your first comment about accepting solutions :). – Gökhan Barış Aker Sep 04 '12 at 16:58
  • I checked references for variables and non of them is nil. In addition i'm using __unsafe_unretained reference to UITextFields, which are connected with strong reference to their parent UIView object by default. Also, your comment about returning NO when i set the text seemed interesting. Can you explain exactly where should i return NO. Is it textField:shouldChangeCharactersInRange:replacementString:? if yes text field not updating when i return NO. – Gökhan Barış Aker Sep 04 '12 at 16:59