iOS:在多个后台线程完成之前不要从函数返回

标签 ios objective-c

这看起来应该很简单,但我遇到了很多麻烦。我有一个函数可以触发一堆在后台运行并具有完成 block 的其他函数。我希望我的函数等到所有完成 block 都被调用后再返回。

我无法控制我正在调用的在后台执行的函数。否则我只会修改它以将 dispatch_async 与我自己的队列一起使用,然后等待该队列完成。

我的情况示例:

- (void)functionThatShouldBeSynchronous {
    for (int i = 0; i < 10; i++) {
        [self doSomethingInBackground:^{
            NSLog(@"completed!");
        }];
    }
    // How do I wait until all 10 threads have completed before returning?
}

- (void)doSomethingInBackground:(void(^)())completion {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        [NSThread sleepForTimeInterval:1.0f]; // Do stuff
        completion(); // Execute completion block
    });
}

提前致谢。

最佳答案

使用这样的调度组:

- (void)functionThatShouldBeSynchronous {
    dispatch_group_t taskGroup = dispatch_group_create();

    for (int i = 0; i < 10; i++) {
        dispatch_group_enter(taskGroup);
        [self doSomethingInBackground:^{
            NSLog(@"completed!");
            dispatch_group_leave(taskGroup);
        }];
    }

    // Waiting for threads
    dispatch_group_wait(taskGroup, DISPATCH_TIME_FOREVER);
    dispatch_release(taskGroup);

    // Background work complete
}

如果你想要等待线程超时,你可以将 dispatch_group_wait 行更改为此

// Waiting 10 seconds before giving up
if (dispatch_group_wait(taskGroup, dispatch_time(DISPATCH_TIME_NOW, 10000000000)) != 0) {
    // Timeout
}

该参数以纳秒为单位。

正如 bbum 所说,您不应该阻塞主线程。在这种情况下,您可以这样做:

typedef void(^MyCompletionHandler)();
-(void)functionDoingBackgroundWorkWithCompletionHandler:(MyCompletionHandler)completionHandler {
    dispatch_group_t taskGroup = dispatch_group_create();

    for (int i = 0; i < 10; i++) {
        dispatch_group_enter(taskGroup);
        [self doSomethingInBackground:^{
            NSLog(@"completed!");
            dispatch_group_leave(taskGroup);
        }];
    }

    dispatch_queue_t waitingQueue = dispatch_queue_create("com.mycompany.myapp.waitingQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(waitingQueue, ^{
        // Waiting for threads
        dispatch_group_wait(taskGroup, DISPATCH_TIME_FOREVER);
        dispatch_release(taskGroup);


        // Background work complete
        dispatch_async(dispatch_get_main_queue(), ^{
            // Calling the completion handler on the main thread (If you like)
            completionHandler();
        });
        dispatch_release(waitingQueue);
    });
}

关于iOS:在多个后台线程完成之前不要从函数返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16512898/

相关文章:

objective-c - 在 iOS 4 中,只有点击按钮两次,UIActionSheet 才会起作用

ios - 如何将 UIButton 左对齐,UILabel 右对齐。喜欢 instagram 的评论

ios - 停止在 UITableViewCell 中重复值

iOS7 也从 ViewDidLoad 调用 IBAction 方法

iphone - 通过iPhone上的着色器处理视频时捕获视频

ios - 如何获得通用链接来打开应用程序而不是 safari?

ios - 根据底层内容更改 StatusBar 文本颜色

objective-c - 如何在 objective-c 中将文件转换为这种十六进制表示法?

ios - 带导航栏的 ScrollView +自动布局

ios - 使用 Swift 的 UICollectionView 错误