Reputation: 2873
I am trying to run a while loop when I push the button, but I can not push the button because the while loop blocks the UI.
Is there a background thread where I can run the while loop and also push the UIButton
?
Upvotes: 24
Views: 29364
Reputation: 776
I thought I'd share that there are different levels of priority for concurrent queues, their quality of service equivalent, and useful (albeit subjective) recommended use scenario for timing. More can be found from Apple's docs.
Global queue | Corresponding QoS class | Description
--------------------------------------------------------------------------
Main thread | User-interactive | Instantaneous
DISPATCH_QUEUE_PRIORITY_HIGH | User-initiated | <= 3s
DISPATCH_QUEUE_PRIORITY_DEFAULT | Default | 3s - 10s
DISPATCH_QUEUE_PRIORITY_LOW | Utility | 3s - 3m
DISPATCH_QUEUE_PRIORITY_BACKGROUND | Background | > 3m
For completeness, there is also the unspecified
QoS, but it's only used for supporting legacy APIs.
Some examples:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{});
Upvotes: 1
Reputation: 363
Try this
dispatch_async(dispatch_get_main_queue(), ^{
// your code
});
Once it dispatches, you will not have full control over the operation. If you want to take the control of the operation. Use
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// Background work
}];
Upvotes: 4
Reputation: 1243
Way 1 :
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Write your code here
});
Way 2 :
If you use performSelectorInBackground:withObject:
to spawn a new thread.
Way 3 :
[NSThread detachNewThreadSelector:@selector(yourMethod:) toTarget:self withObject:nil];
Upvotes: 6
Reputation: 1806
You can use dispatch_async for this purpose.You have to run the loop in the background thread, while the UI updates must be done in the main thread.Here is a link
Upvotes: 0
Reputation: 1177
Personally, I'd run a HUD activity indicator over the top of the UI and then run your loop in the background.
//Start the HUD here
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//Run your loop here
dispatch_async(dispatch_get_main_queue(), ^(void) {
//stop your HUD here
//This is run on the main thread
});
});
Upvotes: 59
Reputation: 36
There are many options for you, Grand Central Despatch is a good option, or you could use a NSTimer to trigger an event in the background every x milliseconds which may also work for you.
dispatch_async(dispatch_get_main_queue(), ^{
// your code
});
Or
NSTimer *refreshTimer;
refreshTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(YourMethodHere) userInfo:nil repeats:YES];
Upvotes: 0