19

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,246
  • 20
  • 88
  • 102
Martin
  • 2,743
  • 11
  • 40
  • 63
  • 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

5 Answers5

49

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,077
  • 1
  • 14
  • 23
2

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
  • 343
  • 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
1

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,113
  • 12
  • 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
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,790
  • 4
  • 23
  • 46