23

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?

JJJ
  • 32,902
  • 20
  • 89
  • 102
Martin
  • 2,813
  • 11
  • 43
  • 66
  • 1
    Have a look at this page: http://stackoverflow.com/questions/7055424/ios-start-background-thread – Matz Dec 09 '14 at 09:15
  • Read also about [Grand Central Dispatch](https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/index.html) – michal.z Dec 09 '14 at 09:16

6 Answers6

57

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


    });
});
Compy
  • 1,157
  • 1
  • 12
  • 24
5

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];
virus
  • 1,203
  • 13
  • 21
  • Would be a better answer if you add the NSOperation usage and also include the important concept of moving between the main and the background threads for each method. – Tommie C. Oct 16 '18 at 23:11
4

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
}];
Dev
  • 363
  • 2
  • 9
  • If I use `dispatch_async` to start background working , how do I end this work? – Martin Dec 09 '14 at 09:21
  • once it dispatches in queue,you will not have control over your code. drop your while loop inside. – Dev Dec 09 '14 at 09:26
0

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];
Andy Grant
  • 36
  • 2
  • If I use dispatch_async to start background working , how do I end this work? – Martin Dec 09 '14 at 09:22
  • @Martin: You have to use "cooperative cancellation": state that you can change from the outside to say "you should stop working" and code inside the block that checks that state at regular intervals. – Jesper Dec 09 '14 at 09:27
0

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

humblePilgrim
  • 1,818
  • 4
  • 25
  • 47
0

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), ^{});
h.and.h
  • 690
  • 1
  • 8
  • 26