相关疑难解决方法(0)

如何停止在调度队列中执行任务?

如果我有一个串行队列,我怎么能从主线程告诉它立即停止执行并取消其所有任务?

iphone xcode multithreading grand-central-dispatch ios

52
推荐指数
5
解决办法
6万
查看次数

Objective-C,使用UI事件取消调度队列

场景:

  • 用户点击一个按钮,要求对地址簿进行某种修改.
  • 调用方法以启动此修改,并显示警报视图.
  • 为了显示警报视图并保持UI响应,我使用了dispatch_queue:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                     dispatch_sync(dispatch_get_main_queue(), ^{
                       // Show the alert view
                     });
                   });
    
    Run Code Online (Sandbox Code Playgroud)
  • 使用以下命令启动地址簿修改过程:

    dispatch_async(modifyingAddressBookQueue, ^{});
    
    Run Code Online (Sandbox Code Playgroud)

现在,我想让用户随时取消该过程(当然在保存地址簿之前).因此,当他点击警报表中的取消按钮时,我想访问调度块,设置一些特定的BOOL来停止进程并还原地址簿.

问题是,你做不到!您无法访问该块并更改其中的任何变量,因为所有变量只复制一次.块执行时块内变量的任何变化都不会被块看到.

总结一下:如何使用UI事件停止正在进行的操作?

更新:

该过程的代码:

- (void) startFixingModification {

    _fixContacts = YES;
    __block BOOL cancelled = NO;

    dispatch_queue_t modifyingAddressBookQueue;
    modifyingAddressBookQueue = dispatch_queue_create(sModifyingAddressBookQueueIdentifier,
                                                      NULL);

    dispatch_async(modifyingAddressBookQueue, ^{

        for (NSMutableDictionary *contactDictionary in _contactArray) {

            if (!cancelled) {
                break;
            }

            i = i + 1;

            BOOL didFixContact = [self fixNumberInContactDictionary:contactDictionary];
            if (!didFixContact) {
                _fixedNumbers = _fixedNumbers - 1;
            }

            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
                dispatch_sync(dispatch_get_main_queue(), ^{
                    [self …
Run Code Online (Sandbox Code Playgroud)

iphone concurrency objective-c grand-central-dispatch ios

15
推荐指数
2
解决办法
2万
查看次数

杀死iOS中dispatch_async队列中的项目

我使用dispatch_async在后台运行一堆项目,有时我想杀死队列中的内容 - 这可能吗?例如,此代码在视图上运行,然后用户返回屏幕.无论后退导航如何,所有这些已触发的操作都会继续运行.理想情况下,我想从运行中杀死这些项目:

dispatch_async(dispatch_get_global_queue(2, 0), ^{
        for (int i=0; i<[self.manufacturers count]; i++) {
            NSString *manufacturerID = [[[self.manufacturers objectAtIndex:i] ManufacturerID] stringValue];
            [self doSync:manufacturerID withIndex:i setTimer:YES];
        }
    });
Run Code Online (Sandbox Code Playgroud)

如果我创建一个队列并命名它,然后在视图的dealloc上释放它,这将被调用,它们仍然继续运行.

objective-c grand-central-dispatch ios5

10
推荐指数
1
解决办法
2万
查看次数

如何在只处理最新请求的iOS中实现工作队列?

在我的iOS程序中,会发生以下情况:当用户键入时,会向启动数据库查找的线程触发请求.完成数据库查找后,将在主线程上触发响应,以便应用程序显示结果.

这非常有效,但如果用户输入的速度非常快,则可能会有多个请求在飞行中.最终系统将赶上,但似乎效率低下.

是否有一种巧妙的方法来实现它,以便在启动请求时,我可以检测到查询已在进行中,而请求应该存储为"可能最新的超过飞行中的那个"?

下面添加评论的示例解决方案

这是一个小型示例项目的视图控制器的主体,用于说明解决方案的属性.键入时,您可能会得到如下输出:

2012-11-11 11:50:20.595 TestNsOperation[1168:c07] Queueing with 'd'
2012-11-11 11:50:20.899 TestNsOperation[1168:c07] Queueing with 'de'
2012-11-11 11:50:21.147 TestNsOperation[1168:c07] Queueing with 'det'
2012-11-11 11:50:21.371 TestNsOperation[1168:c07] Queueing with 'dett'
2012-11-11 11:50:21.599 TestNsOperation[1168:1b03] Skipped as out of date with 'd'
2012-11-11 11:50:22.605 TestNsOperation[1168:c07] Up to date with 'dett'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,将跳过第一个排队的操作,因为它在执行其工作的冗长部分时确定它已经过时.以下两个排队操作('de'和'det')在被允许执行之前被取消.最后的最终操作是唯一真正完成所有工作的操作.

如果您注释掉[self.lookupQueue cancelAllOperations]行,则会出现以下行为:

2012-11-11 11:55:56.454 TestNsOperation[1221:c07] Queueing with 'd'
2012-11-11 11:55:56.517 TestNsOperation[1221:c07] Queueing with 'de'
2012-11-11 11:55:56.668 TestNsOperation[1221:c07] Queueing with 'det'
2012-11-11 11:55:56.818 TestNsOperation[1221:c07] Queueing with 'dett'
2012-11-11 11:55:56.868 TestNsOperation[1221:c07] Queueing with 'dette' …
Run Code Online (Sandbox Code Playgroud)

concurrency objective-c ios

2
推荐指数
1
解决办法
2236
查看次数