【问题标题】:A method inside async bock is not being called未调用异步块中的方法
【发布时间】:2013-08-18 20:55:10
【问题描述】:

我的代码如下所示,我尝试在异步块内调用 cpu 密集型方法,但该方法并不总是被调用,有时会被调用,有时不会。

-(IBAction) aMethod
//some code

    dispatch_async(backgroundQueue, ^{

        NSArray *allFiles = [appDel getAllFiles];
        totalFilesCount = [allFiles count];
    });
//some code
}

backgroundQueue是接口文件中声明的实例变量,在viewDidLoad方法中创建:

 backgroundQueue = dispatch_queue_create("com.myapp.backgroundprocessing", NULL);

getAllFiles 方法有时被调用,有时不被调用(用断点检查),我将它调用到 dispatch_async 块中的原因是返回结果需要很长时间。我的方法似乎有什么问题,尽管它是 CPU 密集型方法,但是否应该在主线程中调用它?

【问题讨论】:

  • 你能用你创建背景队列的方式更新你的代码
  • 我不明白为什么不应该调用它,但是如果 backgroundQueue 是一个串行队列,那么在之前的调用完成之前它不会被调用。
  • @sbarow,我刚刚编辑了我的帖子,backgroundQueue 基本上是一个实例变量,我没有将它声明为属性。
  • @Malloc: dispatch_queue_create(..., NULL) 创建一个串行队列。
  • @MartinR 啊我明白了,那么应该是什么类型?你能详细说明答案吗?谢谢

标签: ios multithreading grand-central-dispatch


【解决方案1】:
backgroundQueue = dispatch_queue_create(..., NULL);

创建一个 serial 队列,而不是您假设的并发队列。 因此,块调度与

dispatch_async(backgroundQueue, ^{ ... });

当所有先前分派到该队列的块都完成时执行。 因此,如果第一次调用仍在运行,它可能看起来好像第二个块 根本没有执行。

要创建并发队列,您可以使用

backgroundQueue = dispatch_queue_create(..., DISPATCH_QUEUE_CONCURRENT);

但是您应该检查在您的情况下是否有必要开始另一个 (长时间运行)[appDel getAllFiles] 操作如果之前的操作还在 正在运行。

一种可能的替代方法是仅启动另一个[appDel getAllFiles] 操作 如果上一个已经完成,如果上一个操作什么也不做 仍在运行。这可以做到,例如带有NSOperationQueue:

if ([opQueue operationCount] == 0) {
    [opQueue addOperationWithBlock:^{
        NSArray *allFiles = [appDel getAllFiles];
        totalFilesCount = [allFiles count];
    }];
}

【讨论】:

    猜你喜欢
    • 2015-03-12
    • 1970-01-01
    • 2015-09-14
    • 2015-04-14
    • 2013-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多