Question

I have 2 blocks with dispatch_sync, when the first block ends I show the window for the user and starts run the second block. But I'm not getting click any button on the screen until the second block ends..

Look the code:

[HUD showUIBlockingIndicatorWithText:@"Loading..."];
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^ {
        dispatch_sync(dispatch_get_main_queue(), ^{
                [UIView beginAnimations:@"fade" context:nil];
                [UIView setAnimationDuration:0.5];
                self.capa.alpha = 0.0;
                [UIView commitAnimations];
                [HUD hideUIBlockingIndicator];
        });
});

dispatch_barrier_async(queue, ^ {
    //code executed in the background
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"entrou na foto");
        //[self getFotos];
    });
});
Was it helpful?

Solution

If you call any code on the main thread, it will block your UI, so calling

dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"entrou na foto");
    [self getFotos];
});

will block your UI until [self getFotos] has returned.

OTHER TIPS

A couple of reactions.

  1. The pattern you've used here doesn't quite make sense. Making some inferences from your code sample, I would have thought that the desired pattern would be:

    • Just start the HUD (or some spinning activity indicator view) in the main queue;

    • Dispatch all of your separate time consuming processes in the background queue; if they can operate concurrently, you'd use dispatch_async to your queue; and

    • Do a final dispatch_barrier_async of your completion block (i.e. your indication that all of the other blocks dispatched to your concurrent queue are done), which does the dispatch_async (not sync, generally) back to the main queue to stop the HUD.

  2. There's nothing in this code sample that would suggest anything that would make your UI unresponsive, so I would have to suspect something in the portions of code that you've removed for the sake of clarity/brevity. In general, there are two things that might make your UI unresponsive:

    • Obviously, if there's anything dispatched back to the main queue that is slow. For example, you have a getFotos method, but we don't know what that does, but if it was slow, that would cause a problem. There's nothing obviously in this category of your snippet, but it's one class of problem to be aware of.

    • The more subtle problem can be if there's something in that slipped into that background queue accidentally that is UI related. Ironically, that can often cause a UI to freeze for a bit. You'd have to share the details of what you're doing in that block dispatched to the background for us to advise you further on that.

    But those are the only two things that leap out at me that could cause your UI to become temporarily unresponsive.


Completely unrelated to your performance issues, but I wouldn't generally advise the old-style animations. As the docs say, "... this method is discouraged in iOS 4.0 and later." So I'd suggest removing the lines that say:

[UIView beginAnimations:@"fade" context:nil];
[UIView setAnimationDuration:0.5];
self.capa.alpha = 0.0;
[UIView commitAnimations];

Instead, I'd suggest you to use block-based animation, such as:

[UIView animateWithDuration:0.5 animations:^{
    self.capa.alpha = 0.0;
}];

You may want to use dispatch groups here. Dispach a block into background & into the group with the UI disabled, and then you can spawn a waiting thread calling dispatch_group_wait blocking it until task is done to re-enable the UI. Only the disabled parts are locked. and everything else will work

dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, /* queue */, ^{ /* ... */ });
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
               ^{
                   dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
                   // This thread will be blocked until background tasks are done.
                   dispatch_async(dispatch_get_main_queue(),
                   ^{ /* ... */ });
               });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top