0

I have written a background processing logic using dispatch_async as follows:

- (IBAction)textFieldChanged:(id)sender {
dispatch_async(kBgQueue, ^{
     NSArray *tempArray = [myClass getSuggestionArray]; //getSuggestionArray returns an array of objects from a database
        [self performSelectorOnMainThread:@selector(initSuggestionArray:) withObject:tempArray waitUntilDone:YES];
    });
}

As you can see, this method gets called everytime user edits the textfield (as soon as user types a letter). kBgQueue is defined as:

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

What I want is some method, some logic so that whenever user edits the field I can check whether there is already a queued task in this kBgQueue or not and if it is, then I want to stop the execution of that queued job before starting the next block.(want to remove the previous one) I am using this so that the UI of the application doesn't look like it hanged, if user types 3-4 characters quickly (because result is coming too late from my database)

anshul
  • 846
  • 1
  • 14
  • 32

1 Answers1

1

You could use an NSOperationQueue instead of your GCD queue and add operations like this:

[queue addOperationWithBlock:^{
    NSArray *tempArray = [myClass getSuggestionArray];
    dispatch_async(dispatch_get_main_queue(), ^{
        [self initSuggestionArray:tempArray];
    });
}];

Then you can cancel all your operations with

[queue cancelAllOperations];

If you need finer grained control you could subclass NSOperation and add some checks to see if the operation has been cancelled.

tim
  • 1,682
  • 10
  • 18
  • Hey tim, I think the operations are not getting cancelled because initSuggestionArrayMethod is getting called every time, event after cancelling the operation. The gdb is showing logs as: void _WebThreadLockFromAnyThread(bool), 0x7a9cf60: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread. – anshul Mar 10 '12 at 09:41
  • You could also use an NSBlockOperation and check if has been cancelled before calling initSuggestionArray, you can find an example here: http://stackoverflow.com/a/8113232/381870 – tim Mar 10 '12 at 09:46