0

In my iOS app the user can open projects, which are loaded from disk. It takes some time, so I present my custom loading view, which is subclass of UIView. This loading view has a label which acts like a progress bar. I'm trying to constantly update its value.

Here is first approach (I simplified my code a bit):

// in view controller, which has projects list

[self performSelectorInBackground:@selector(openLoading) withObject:nil];

[projectsManager loadProject:project statusChangedCallback: ^(NSString* status){ 
    self.loadingDialog.progressString = status;
}];

[self closeLoading];

// in ProjectsManager

-(void) loadProject:(NSString*)project statusChangedCallback:(void(^)(NSString* status))callback
{
    callback(@"Loading some data...");
    [self loadSomeDataFrom:project];

    callback(@"Loading other data...");
    [self loadOtherDataFrom:project];
}

this approach does not work (UILabel does not updating) because I am updating it multiple times from main queue in one loop cycle. I also tried different approaches like:

[projectsManager loadProject:project statusChangedCallback: ^(NSString* status){ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        self.loadingDialog.progressString = status;
    });
}];

but such an update for the label in background does not work too probably because of the same reason - main loop is stopped. I would like to put all my project loading into background thread, so main loop will not be affected, but this is impossible, because project loading closely tied with some OpenGL textures loading which can be performed only in main thread.

I've also tried sending -setNeedsDisplay to view, but this did not work too.

So, how can I make the label updating while main queue is busy? Maybe, I need to change the architecture of mechanism of presenting loading view?

4

1 回答 1

0

The values are not getting update because you are using a background queue, and it's not possible to update UI in any thread beside the main thread, dispatch_get_global_queue, still use a background thread, use dispatch_get_main_queue for any changes in the UI.

Try:

dispatch_async(dispatch_get_main_queue(), ^{ self.loadingDialog.progressString = status; })

于 2013-11-01T16:59:51.547 回答