如何在Objective-C中使用后台线程?

24

我试图在按下按钮时运行while循环,但由于while循环阻塞了UI,所以无法按下按钮。

是否有后台线程可以运行while循环,并同时按下UIButton


1
请查看此页面:https://dev59.com/XWw05IYBdhLWcg3wwEUS - Matz
还可以阅读有关Grand Central Dispatch的内容。 - michal.z
6个回答

58

就我个人而言,我会在UI的顶部运行一个HUD活动指示器,然后在后台运行你的循环。

//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


    });
});

5

方法一:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Write your code here 
});

方法2:

如果你使用performSelectorInBackground:withObject:来创建一个新的线程。

方法3:

[NSThread detachNewThreadSelector:@selector(yourMethod:) toTarget:self withObject:nil];

如果您添加NSOperation的使用,并为每种方法包括在主线程和后台线程之间移动的重要概念,那么这将是一个更好的答案。 - Tommie C.

4

试试这个

dispatch_async(dispatch_get_main_queue(), ^{
//  your code
});

一旦它被分派,您将不能完全控制操作。 如果您想控制该操作,请使用

NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{

   // Background work
}];

如果我使用dispatch_async开始后台工作,如何结束这项工作? - Martin
一旦代码进入队列,您将无法控制它。请将while循环放在其中。 - Dev

0

您可以使用dispatch_async来实现此目的。您必须在后台线程中运行循环,而UI更新必须在主线程中完成。这里是一个链接


0

对于您来说,有很多选择。Grand Central Despatch 是一个不错的选择,或者您可以使用 NSTimer 在后台每 x 毫秒触发一个事件,这也可能适合您。

dispatch_async(dispatch_get_main_queue(), ^{
//  your code
});

或者

NSTimer *refreshTimer;
refreshTimer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(YourMethodHere) userInfo:nil repeats:YES];

如果我使用dispatch_async来启动后台工作,那么我该如何结束这项工作? - Martin
@Martin:你必须使用“协作取消”:即声明可以从外部更改以表示“你应该停止工作”,并在代码块内定期检查该状态。 - Jesper

0

我想分享一下,针对并发队列有不同的优先级级别、它们的服务质量等效性以及时间安排方面有用的(尽管是主观的)推荐使用场景。更多信息可以在苹果文档中找到。

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

为了完整性,还有一个unspecified QoS,但它仅用于支持旧版API。

一些例子:

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), ^{});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接