You can use Grand Central Dispatch for this:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, kNilOptions), ^{
// Call your method.
});
Question
Pretty generic question, is there a way to call a method I have every so often with the application without blocking the UI load?
Solution
You can use Grand Central Dispatch for this:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, kNilOptions), ^{
// Call your method.
});
OTHER TIPS
You definitely want to use Grand Central Dispatch to do this, but I'd just like to point out that GCD has a method build just for this kind of thing. dispatch_apply()
executes its block a specified number of times on a queue of your choosing, of course, tracking which iteration you're on along the way. Here's an example:
size_t iterations = 10;
dispatch_queue_t queue = dispatch_queue_create("com.my.queue", DISPATCH_QUEUE_SERIAL);
dispatch_apply(iterations, queue, ^(size_t i) {
NSLog(@"%zu",i);// Off the main thread.
dispatch_async(dispatch_get_main_queue(), ^{
// Go back to main queue for UI updates and such
});
});
You could use:
[self performSelectorInBackground:@selector(aMethod) withObject:nil];
for a method with no parameters. Or something like
[self performSelectorInBackground:@selector(otherMethodWithString:andData:) withObjects:string, data, nil];
if you have parameters.
Here's another example, explaining how to execute background queues and iterate with the user inside it.
- (void)method
{
// start a background proccess that will not block the UI
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i < 1000000; i++) {
if (i == 999) {
// Need to iterate with interface elements when inside a background thread.
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Found" message:@"Found your number" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alertView show];
});
}
NSLog(@"Count: %d",i);
}
});
}
Using GCD is definitely a good way to go, as others have noted.
Alternatively, if you want the operation to be cancelable (e.g. loading a web resource), you might consider subclassing NSOperation
and checking for isCancelled
.
(AFNetworking actually does this (e.g. AFHTTPRequestOperationManager
) in making / managing web requests.)
Checkout the Apple docs on NSOperation
and also this tutorial on Ray Wenderlich's site for more details on NSOperation
s.