Search code examples
cocoa-touchuikituiprogressview

Cocoa Touch ProgressView in Loop not displaying update


If I have an innocuous loop that gets fired off when I press a button like:

- (IBAction)start:(id)sender{
    calculatingProgressBar.progress = 0.0;  
    int j = 1000;
    for (int i=0; i<j; i++) {
        calculatingProgressBar.progress = (i/j);
    }
}

The ProgressView is not updated. In other languages there is a view update command that you have to execute in these circumstances. What is the Cocoa equivalent or do you have to effect some other workaround.


Solution

  • The problem is that the UI is only updated periodically as the run (event) loop turns. A for() loop, which I am assuming runs on the main thread, is going to block the run loop until finished. Not only does this mean the progress bar won't be updated (or, rather, will jump right to 100% at the end), but that you are potentially going to freeze the UI for some time. (I assume, since you are showing a progress bar, that this could take a while.)

    What you want to do, for any lengthy operation, is to have the work done on a separate queue/thread, and call out the update the UI on the main thread periodically. For example, you might try something like (warning: typed in browser):

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    dispatch_async(queue, ^{
        int j = 1000;
        for (int i=0; i<j; i++) {
            // Do your presumably useful work, not just looping for fun :-)
            dispatch_async(dispatch_get_main_queue(), ^{
                // UI updates always come from the main queue!
                calculatingProgressBar.progress = (i/j);
            });
        }
    });
    

    This example uses GCD (Grand Central Dispatch). There are higher level constructs you can also look at, like NSOperationQueue, but the basic idea remains the same.

    If you are unfamiliar with concurrent (multithreaded) programming, you are going to have a modest learning curve to get up to speed. I suggest starting with the Concurrency Programming Guide.