Vikas Singh
Vikas Singh

Reputation: 1791

How to lazy/async load various elements(data in labels) in a View?

I have a ViewController with various labels. Each of these labels get dynamically populated at the run time based on various regex parsing logic running on an html page. The problem is, each regex match is taking 2-3 seconds and I have 8 such labels so that means i have to wait somewhere around 20-25 seconds before the view shows up!

This is a very very bad user experience. I want that to make this less painful for the user and therefore want to load each label independently as and when they get the data after the regex is processed and not wait for all 8 labels to finish retrieving their regex matches.

Any way this can be achieved in ios 5?

Upvotes: 3

Views: 759

Answers (3)

Bruce Lee
Bruce Lee

Reputation: 4431

if you want to use this, you have to pay some attention to get your code separated. one part do data loading work, the other one set data to controls. and you have to make sure that you sqlite (i assume u used this db) cool with multi thread.

Upvotes: 0

Jack Lawrence
Jack Lawrence

Reputation: 10772

Use Grand Central Dispatch (GCD). It'll handle queues and threading etc for you. There's no need to create a method just for one set of operations that happens once, and regardless, dispatch_async() is faster than performing a selector on a background thread and you get to keep your existing code structure - you just wrap it up in a nice concurrent bundle that won't block the main thread :)

// get a reference to the global concurrent queue (no need to create our own).

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

for each label's regex operation {

dispatch_async(queue, ^{
     // your regex here for one 

     // execute back in the main thread since UIKit only operates in the main thread.

    dispatch_async(dispatch_get_main_queue(), ^{
        [myLabel setText:<result of operations>];
    });
}); 

}

Upvotes: 1

lnafziger
lnafziger

Reputation: 25740

  1. Create a separate function which calculates the values that you need.
    (You probably already have this anyway for code readability/maintainability.)
  2. Run this thread in a background thread.
  3. When you are ready to actually set the text, make sure that you do it on the main thread:

Here is an example:

- (void)calculateLabelText {
    NSString *label1Text = // However you calculate this...
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        self.label1.text = label1Text;
    });

    NSString *label2Text = // However you calculate this...
    dispatch_async(dispatch_get_main_queue(), ^(void) {
        self.label2.text = label2Text;
    });
}

In viewDidLoad, add this:

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

Upvotes: 2

Related Questions