Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you want to do a series of calculations, and show that progress, you have to do the calculations in a background thread, and then update the UI on the main thread. If you did your calculations in the main thread, your UI would never have a chance to update itself.</p> <p>But, assuming that you've successfully initiated your time consuming calculations on a background thread, you could then use a timer (or display link) to update your progress bar, for example, define a timer property:</p> <pre><code>@property (nonatomic, weak) NSTimer *timer; </code></pre> <p>Then schedule a repeating timer from the main queue and start your background process:</p> <pre><code>// start the timer NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(updateProgress:) userInfo:nil repeats:YES]; self.timer = timer; // use whatever mechanism you want for initiating your background process (though dispatch queues and operation queues may be easier than dealing with threads directly) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [self startTimeConsumingProcess] }); </code></pre> <p>You'd then obviously implement an <code>updateProgress:</code> method that updates your UI:</p> <pre><code>- (void)updateProgress:(NSTimer *)timer { // update the UI progress bar here } </code></pre> <p>And don't forget to <code>invalidate</code> that timer when your calculation is done or when the view is dismissed, because if you don't, the timer will maintain strong reference to your view controller and you'll have a strong reference cycle (aka retain cycle).</p> <hr> <p>By the way, the other logical approach, instead of using a timer, is to just have the background calculation dispatch UI updates that update the progress bar back to the main queue, e.g.</p> <pre><code>- (void) startSomeTimeConsumingProcess { // start time consuming process in background queue dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ BOOL finished = NO; while (!finished) { // do something, updating `finished` when done // update UI to report the progress in the main queue, though: dispatch_async(dispatch_get_main_queue(), ^{ // update progress UI here }); } }); } </code></pre> <p>The only consideration with this approach is how quickly this background process dispatches the main queue with progress bar updates. If it updates too quickly, you can backlog the main queue with progress updates. Hence, the appeal of the timer (or display link) based approach, above. But if you're confident that these updates will happen slowly enough, this alternative approach might be easier.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload