Peter M
Peter M

Reputation: 7503

wait_fences: failed to receive reply: 10004003 (Again)

Another cry for help about this warning.

First of all I have looked at every and all questions on here elsewhere and none seem to fit my situation. It has nothing to do with Alert boxes and resigning as first responder, nor performing any animation before views get displayed. My problem occurs when instantiating a UIView based custom keyboard.

Secondly, I believe that I can make the warning appear/disappear at will. I am just very confused as to why, so I am looking more for an explanation than a solution.

There is too much code to post here, so I'll just give an outline of what is going on:

The ViewController "Calc" instantiates a custom UIView based "DataView" in the VC's loadView method, and then adds it as a sub view of the VC.

The "DataView" instantiates a custom UITextField based "TextFieldKPD" in the DataView's init method

The "TextField" instantiates a custom UIView based "KeyPad" in the TextField's init method, and assigns that KeyPad to the TextField's inputView.

The "KeyPad" creates 13 UIButtons of type UIButtonTypeCustom, reads in and assigns a "pressed" and "not pressed" image for each button, as well as setting actions for the buttons. It then adds each button as a subview of itself. (By controlling when in the UIView lifecycle of the KeyPad that this construction occurs, is how I can effect the wait_fences warning: see below.)

The "Calc" ViewController is the one that is initially presented to the user. I have tracked down the wait_fences warning as occurring after the end of the Calc's viewDidLayoutSubViews method and before its viewDidAppear method is called. Note that the KeyPad is not visible when the Calc is displayed.

I appear to be able to control the action of the wait_fences warning by changing how the Keypad is constructed:

There is no animation or anything in Calc's loadView. It is instantiate and assign all the way down.

So any comments on this version of wait_fences?

EDIT 1, Jan 30th - Now With Even More Confusion!

I was bored this morning so I decided to play with my code to see if I could better isolate the generation of the warning. I narrowed it down to the following, totally useless code that with which I can now trigger the warning:

-(void)loadImages
{
    UIImage* image;

    for(int i=0; i<16; i++) {
        image = [UIImage imageNamed:@"StupidFileNameThatDoesNotExist"];
    }
}

If I perform [self loadImages] in the init method of KeyPad then the warning appears. But this code does nothing as the file does not exist. I believe that if the loop counter is small enough that the warning does go away, but I haven't qualified a lower limit.

If I replace the actual loading of the image with

[UIImage imageWithContentsOfFile:@"StupidFileNameThatDoesNotExist"]

and still call the method during the KeyPad init, then I do not seem to get the warning. One obvious difference between these two ways of loading the image is that imageNamed caches the image internally.

So I am leaning towards George's answer that it is an internal Apple screw up.

Edit 2, Feb 1 - Its a warning Jim, but not as we know it

So I convinced myself that it was the caching in the UIImage class that was obviously causing the issue. What to do about it? Well write my own image cache of course!!

So I started plugging away, rip out that code that attempted to load invalid images and got the point where I generated the file names I needed and passed them to my cache controller. So to verify that things were starting to come together, within the cache controller, I generated a NSLog message for each attempt to cache an image - nothing more - just log the file name.

And guess what - I get the stupid warning again. For doing no actual work at all.

I can only conclude that there is some sort of internal iOS race condition that I am triggering when I cram extra code into the init method of KeyPad. And that there is nothing I can do to mitigate it. All I can do is hope that this warning is benign.

Edit 3, Hamlet Act 1 scene 4: Something is rotten in the state of Denmark

Keeping the same code as in Edit 2, I commented out the NSLog statement. And the warning went away. I put it back, and the warning appears.

So the code I have is:

-(void)loadImages
{
    // Iterate over button definitions and cache the required images
    for(int i=0; i<numKeys; i++) {

        if (![imageCache imageExistsForTag:keyTags[i]]) {
            [imageCache addImageFile:[NSString stringWithFormat:@"%s_NP.png",keyNames[i]] forTag:keyTags[i]];
        }

        if (![imageCache imageExistsForTag:keyTags[i]+pressedOffset]) {
            [imageCache addImageFile:[NSString stringWithFormat:@"%s_P.png",keyNames[i]] forTag:keyTags[i]+pressedOffset];
        }

    }

}

And:

-(void)addImageFile:(NSString*)imageFile forTag:(int)tag
{
    NSLog(@"Adding tag:%d for file %@", tag, imageFile);
}

With that NSLog statement controlling the appearance of the warning.

Edit 4, Feb 2 - Welcome to the Temple of Doom

Taking Allen's comments to heart I rebuilt my keyboard as a XIB and loaded that instead of manually trying to build the view. Of course that didn't fix anything. I had hoped that the Nib loading would happen outside of what ever it is that is causing the problem.

My gut feeling is that I am butting up against a race condition within the loadView of Calc and some internal iOS activity. If I do too much work inside loadView then I cross the line and trip a wait_fences warning. And that the keyboard is a symptom and not the underlying cause. IE it could have been any activity, it was just that the keyboard work was the last thing I did before the warning started appearing. I just wish that I actually knew what the constraints were that I was actually crossing and not stumbling around in the dark.

Upvotes: 2

Views: 1291

Answers (5)

ader
ader

Reputation: 5393

? I'm a little unclear of your view/viewcontroller hierarchy...

You've got a ViewController "Calc" which creates a "DataView" for it's "master" view. "DataView" creates a textField "TextFieldKPD" as a subview of itself. "TextFieldKPD" then creates a UIView "KeyPad" subview which itself creates 13 UIButton subviews for itself.

So your views are 4 levels deep?

Apple state that a ViewController should handle a whole screenful of views (I guess this changed slightly now that we can create containerViews but the intent behind their assertion remains). Make sure your keypad button events and textfield events are handled by your viewController.

Surely you would be better creating all of these views in the viewController or the master view so your hierarchy is flatter?

Apologies if I've misunderstood your hierarchy.

Btw, one thing to try is removing the textfield entirely and seeing if you can still get the error.

Upvotes: 0

kumar123
kumar123

Reputation: 889

According to my knowledge. This warning appears when we are calling a UIAlertView and at the same time we are performing some operation on the UIView. To solve this problem we need not to perform operation on UIView at that time. For this we can do either of the two things : 1. We can call UIAlertView with some delay so that the operation on the UIView gets completed. 2. Or we can perform the operations on the UIView in method - (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; So that the UIAlertView is not on our UIView at that time when some operations are performing on the UIVIew.

Hope it will help you.

Upvotes: 0

Marc Charbonneau
Marc Charbonneau

Reputation: 40515

I've ran into the wait_fences error when mistakenly running UIKit code from a background thread. It doesn't sound like that's your problem, but if you haven't yet that's another thing to look into.

Upvotes: 0

valvoline
valvoline

Reputation: 8117

As far as i can tell about your code description, the problem seems to occur when a subview (eg. UIAlertView) is created prior to its parent/super view. Something to do with the responder chain.

Try moving the view codes around to fix the problem or paste the relevant parts.

Upvotes: 2

George Green
George Green

Reputation: 4905

I've had this issues a few times before and attempted to find a solution. The closest that I got was that according to an apple engineer it is an issue caused internally and 3rd party developers should not worry about it. As far as I am aware it shouldn't cause your app to crash or cause any problems, other than a really annoying error in the debugger that seems to drive all developers mad!

Sorry that I couldn't be of more help.

Upvotes: 2

Related Questions