Objective-C在主线程上运行方法而不阻塞它

时间:2013-10-27 23:07:46

标签: ios objective-c multithreading grand-central-dispatch

我知道这听起来不对!但我需要实现的是在主线程上运行一个巨大的枚举,这显然会阻止整个应用程序。我正在寻找的是循环周期之间的动画或延迟,以便其他代码可以有机会执行。 这是我的代码:

for (NSTextCheckingResult* match in matchedArray) {
    dispatch_async(dispatch_get_main_queue(), ^{
        [self addAttributes:@{NSBackgroundColorAttributeName:[UIColor redColor]} range:match.range];
    });
}

如评论所述,此代码与UI相关,必须在主线程上运行。

我也试过了dispatch_after,但好像它会在等待时阻塞线程。无论如何,我可以做到这一点,还是我必须重写我的整个逻辑?!

2 个答案:

答案 0 :(得分:3)

当您在主线程上运行时,matchedArray中的每个元素都会按顺序处理。因此,您可以通过将一个块调度到数组的进程元素 n 来实现您希望与主队列上的其他任务进行交错,该数组在执行任务后将一个块调度到进程元素 n + 1

一些事情(所有代码直接输入答案):

- (void) processIndex:(NSUInteger)index ofArray:(NSArray *)matchedArray
{
   NSTextCheckingResult *match = matchedArray[index++];
   [self addAttributes:@{NSBackgroundColorAttributeName:[UIColor redColor]}
                 range:match.range];
   if(index < matchedArray.count)
      dispatch_async(dispatch_get_main_queue(),
                     ^{ [self processIndex:index ofArray:matchedArray]; });
}


...

if (matchedArray.count > 0)
   dispatch_async(dispatch_get_main_queue(),
                  ^{ [self processIndex:0 ofArray:matchedArray]; });

HTH

答案 1 :(得分:0)

与其他评论者一样,我也对主要线索声明中的“应该”表示怀疑,但我会怀疑你比我更了解你的情况......

您可以编写“巨大的枚举”来将中间状态存储在某种变量或结构中,让它运行X次迭代,然后使用完成处理程序来发出延迟调用[self performSelector:@selector(crazyEnumerationMethod:) withObject:nil afterDelay:2.0]:

一旦处理完所有数据后你就不得不设计某种标志来阻止该方法再次发射。

基本上你会多次遍历数据集,每次迭代都会暂停一次,直到最后处理完所有数据并且标志翻转以防止再次迭代。

根据你的“巨大枚举”所要求的,这可能是一个非常重要的写作过程,但你永远不会知道,也许有一种干净而聪明的方式来存储中间状态并从中断的地方继续每次迭代。