Sunday, June 10, 2012

"wait_fences: failed to receive reply: 10004003'?


I get this cryptic error the first time (and only the first time) my view is loaded due to the following line of code:




- (void)viewWillAppear:(BOOL)animated
{
[textField becomeFirstResponder];
}



There is a noticeable (~3 – 4 second, even on the simulator) delay due to this that makes my app feel unresponsive. Does anyone know how to fix this? I can't find any documentation on it on Apple's site, or any solutions here or on Google.



Strangely, the opposite situation happens if I put the line in -viewDidAppear: instead of -viewWillAppear: ; that is, instead of printing the error only the first time the keyboard is shown and never again, the error is not printed the first time but every time after. This is causing a major headache for me.


Source: Tips4all

14 comments:

  1. Override -viewDidAppear:, not -viewWillAppear, and make sure to call [super viewDidAppear:]. You should not perform animations when you are not on screen ("will appear"). And the -viewDidAppear: docs explain that you must call super because they have their own things to do.

    ReplyDelete
  2. I was getting a similar error when quickly:


    Dismissing a modal view
    Updating the main view
    Presenting a new modal view


    I noticed I was only getting it in the simulator and not on the device. Additionally, I was getting caught in an infinite loop.

    My solution was to delay the presenting of the new modal view. It seems that quickly updating the view hierarchy caused some sot of race condition in Apple's code.

    With that in mind, try this:

    - (void)viewDidAppear:(BOOL)animated{

    [super viewDidAppear:animated];
    [textField performSelector:@selector(becomeFirstResponder) withObject:nil afterDelay:0.1];
    }


    You may be having issues presenting the keyboard for a UITextField that ins't yet on screen.
    This may be causing problems similar to mine.

    Also, you pause giving the hierarchy time to update before presenting the keyboard, just in case.

    Hope this helps.

    ReplyDelete
  3. After trying everything I could find on Google and none of it working, this is what solved the problem for me. The key is that I'm doing this stuff in the willDismissWithButtonIndex delegate method. Before I was doing it elsewhere.

    - (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
    {
    [myTextField resignFirstResponder];
    [myTextField removeFromSuperview];
    [myTextField release];
    }

    ReplyDelete
  4. Check you are only interacting with the UI on the main thread. I got wait_fences: failed to receive reply: 10004003 while I was sitting there waiting for a UIAlertView to show for about 5 seconds because the relevant code was executed on a background thread. You can make sure by putting your code in block and sending it to the main thread:

    dispatch_async(dispatch_get_main_queue(), ^{
    if (!success) {
    // Inform user that import failed
    UIAlertView * importFailedAlert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"ErrorTitle5", @"Import failed")
    message:NSLocalizedString(@"Error5", @"Something went wrong")
    delegate:nil
    cancelButtonTitle:NSLocalizedString(@"OK", nil)
    otherButtonTitles:nil];
    [importFailedAlert show];
    }
    });

    ReplyDelete
  5. After few tests the big rule is: "Do not perform animation before animated dismissal or animated show.".

    For example:


    do not call -dismissModalViewControllerAnimated:YES after the delegation callback of an UIAlertView -alertView:willDismissWithButtonIndex: (wait the fade out of the alert view before doing this using the -alertView:didDismissWithButtonIndex: callback)
    do not try to show the keyboard (becomeFirstResponder) before your view controller is on screen.


    Bad things may happen.

    Hope it will be useful ;-)

    ReplyDelete
  6. If you have the following line in viewDidLoad, it can cause this message. Comment the following line.

    [[UIApplication sharedApplication] setStatusBarHidden:YES]; //This line should be commented


    (You can disable the status bar from the application plist file instead).

    ReplyDelete
  7. If you're running the current iPhone Simulator 4.0, this error message appears frequently when rotating the screen (or when animating after rotating the screen) accompanied by 1-2 second lag in the animations.

    It is a bug in this version of the Simulator and should be fixed soon.

    ReplyDelete
  8. This worked for me to get the keyboard to show itself immediately, without animation or delay.

    Let textField be an instance variable of MyViewController (a subclass of UIViewController).

    Call [textField becomeFirstResponder] in initWithNibName:bundle: (for a subclass of UIViewController) or initWithStyle: (for a subclass of UITableViewController), not in viewDidLoad. E.g.:

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
    [textField becomeFirstResponder];
    }
    return self;
    }


    Or, call it just after initializing but before pushing the UIViewController. E.g.:

    MyViewController *viewController = [[MyViewController alloc] init];
    [viewController.textField becomeFirstResponder];
    [self.navigationController pushViewController:viewController animated:YES];
    [viewController release];

    ReplyDelete
  9. You have done [textfield becomeFirstResponder];

    And after you get the value from textfield in your code, do [textfield resignFirstResponder];. That will help you, I think.

    ReplyDelete
  10. See here for more info: http://www.iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/17373-wait%5Ffences-failed-receive-reply-10004003-a.html

    Your problem is related.

    ReplyDelete
  11. override viewDidappear, not viewWillAppear:

    -(void) viewDidAppear:(BOOL) animated
    {
    [super viewDidAppear:animated];
    [myTextField becomeFirstResponder];
    }

    ReplyDelete
  12. Is the Text Field contained within that view, or within something else? You can only send the 'becomeFirstRepsonder' to something that is contained directly within that view. If it's stored in some other widget component, you shouldn't set the first responder status in this widget, but rather in the widget that's being created. For example, if you're adding the text field to an alert view, because the show happens asynchronously, it might not be up by the time you call the becomeFirstResponder. (Ideally, you'd have your own alert view class and define the text field within that, and when that view receives the viewDidAppear, you'd set the textfield as first responder at that point.)

    ReplyDelete
  13. I also get the message wait_fences: failed to receive reply: 10004003 and my viewWill... and viewDid... methods do nothing but send messages to super. In my case it happens when I have a UIAlertView showing in my GameViewController and the user instead presses the iPhone round device button and then returns to the app. This looks out of my hands.

    ReplyDelete
  14. Also with the UIAlertView. What solved it for me was having the resign as below, as warehouselabs mentioned earlier.

    - (void)didPresentAlertView:(UIAlertView *)alertView
    {
    [txtListingPassword becomeFirstResponder];
    }

    - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
    {
    [txtListingPassword resignFirstResponder];
    }


    The other delegates of UIAlertViewDelegate did not fix the issue.

    ReplyDelete