-2

I got problems with a progress bar that is not updating (it sticks grey). I got this method to update the progress bar in the MainViewController.m:

- (void)setProgress:(float)prog {

    NSLog(@"Progressbar updated, value %f", prog);
    self.progressBar.progress = prog;
}

When I call it from inside the class (inside MainViewController.m) using:

// in MainViewController.m

[self setProgress:1.0];

Everything is working great, the bar shows the progress in blue and I get the NSLog output with value.

With this progress bar I want the visualize the processing that I do in a loop that runs in a different class (processing.m), to send the message with the progress to the MainViewController I'm using a protocol:

#import "progressProtocol.h"

@interface MainViewController : UIViewController <progressProtocol>
- (void)setProgress:(float)prog;

@end

and in the processing.m:

// in processing.m
[self.delegate setProgress:1.0];

When I call the setProgress method by sending a message through the protocol I only get the NSLog output with correct value but the progress bar is not moving according to the value!? When I set a breakpoint inside the method I can see that the method is called but the progress bar is not moving.

Inside the loop I'm sending the message with the new value about several hundert times - but no change at the progress bar at all, only NSLog with correct values. Any idea?

Hecot
  • 89
  • 1
  • 11
  • 2
    Check what is the value of `prog` when you call it with the protocol. – Frankie Nov 30 '16 at 19:16
  • 5
    Is the bar updated on the main thread? It has to. – vadian Nov 30 '16 at 19:17
  • @Frankie: I let NSLog also print the value of prog `NSLog(@"Progressbar updated, value %f", prog);`and the value is passed correct! – Hecot Nov 30 '16 at 19:39
  • 1
    Not enough information. What code calls setProgress? Is it in a loop? Is that code running on the main thread or a background thread? What do you mean "when I call it through a protocol? What other object is sending the messages to your view controller? – Duncan C Nov 30 '16 at 20:17
  • You need to post other pieces of code from where you're calling the above method, with this limited information, you can't expect to get any help. – ldindu Nov 30 '16 at 21:29
  • Oh lordy. I just looked at your edited code. You're creating a view controller and calling setProgress on it without ever displaying that view controller. That new view controller never gets displayed. That's like buying a new car, setting the radio station on it, and then throwing it away and wondering why the radio station on your old car hasn't changed. You need to explain the flow of view controllers in your program if you want help. – Duncan C Dec 01 '16 at 20:16
  • @DuncanC This was just one of my 1000 trials - I already noticed that this was stupid :) Your answer was correct I need to run the loop in background! – Hecot Dec 04 '16 at 23:21

1 Answers1

2

It sounds like you're doing something like this, on the main thread:

int steps = 10000
for (int step = 1; x < steps; x++) {
  //Do something time-consuming that takes a few seconds.
  viewController.setProgress((float)step/(float)steps)
}

That won't work.

UI updates in iOS only take place when your code returns and visits the event loop.

If you have a loop that does a time-consuming task on the main thread and does not return until it's done, your code to update the progress indicator never gets a chance to update the UI.

Instead, you should probably write your code to do the time-consuming work on a background thread:

//Run the time-consuming loop on a background queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
 ^{
    int steps = 10000
    for (int step = 1; x < steps; x++) {
      //Do something time-consuming that takes a few seconds.

      //As the loop progresses, send a message to update the progress 
      //indicator to the main thread.
      dispatch_async(dispatch_get_main_queue(),
      ^{
        viewController.setProgress((float)step/(float)steps)
      }
    }
  }
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • I've set it up according to your scheme and the progress bar is updating well now, but after a certain percent the processing is crashing: `malloc: *** error for object 0x1008b6a00: incorrect checksum for freed object - object was probably modified after being freed.` The processing was working fine before - do you have any idea where to look what causing the crash? – Hecot Dec 04 '16 at 23:31
  • There are various potential gotchas related to multi-threaded programming. It sounds to me like something is getting released while your long-running process is still running. Update your question with your new code at the end, explaining what the long-running code is doing. – Duncan C Dec 05 '16 at 00:18