使用dispatch_sync强制执行顺序 [英] Forcing the order of execution using dispatch_sync

查看:440
本文介绍了使用dispatch_sync强制执行顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的库向以下人员公开了2个API:

My library exposes 2 APIs as follows to:

-(void) createFile{ 

    dispatch_sync(queueSerial, ^{ //B1

     [fileObj createFileInfo:file completion:^(NSError *error){

         //execute completion block C1
     }]; 

    });
}

-(void) readFile:(NSData*)timeStamp{ 

    dispatch_async(queueSerial, ^{ //B2

        [fileObj readFileInfo:fileName completion:^(NSError *error) {
            dispatch_async(queueSerial2, ^{

                //execute completion block C2

            });
         }]

    });
}

readFilecreateFile都是异步方法.

我通常建议使用我的图书馆的人在readFile之前调用createFile.但是,不能保证调用方将如何最终实现它.通常以以下方式调用它(并且我对此无能为力)

I usually recommend to the people using my library to call createFile before readFile. However, there is no guarantee how the callers will end up implementing this. It usually gets invoked in the following fashion (and I have no control over this)

[fileClass createFile];
[fileClass readFile:timeStamp]; 

我要做的是确保在执行completion block C1之后调用readFile.我也不想用createFile阻塞主线程(但是可以放宽这种期望).所以我想要达到的最终结果是:

What I want to do is to ensure readFile gets called after the completion block C1 is executed. I also don't want to block the main thread with createFile (but this expectation can be relaxed). So what I want to achieve as end result is :

  1. 呼叫者(我无法控制)呼叫createFile,并在呼叫readFile
  2. 之后立即
  3. createFile完全执行,完成块C1被触发,之后 那,readFile被派去做它的事情.
  1. Caller (that I have no control over) calls createFile and immediately after calls readFile
  2. createFile fully executes, completion block C1 gets fired and after that, readFile is dispatched to do it's thing.

我该如何实现?

推荐答案

感觉就像您正在尝试采用现有的基于完成处理程序的API并将其引入串行队列模式一样.但是只有当分派的块本身是同步的时,串行队列才有意义. (并且不要将其与dispatch_sync混淆……我们正在谈论的是块内的任务是否异步,而不是您如何将其分派到队列中.)但是,您正在处理被调用的异步方法.来自其他异步方法.

It feels like you're trying to take an existing completion-handler based API and shoe-horn it into a serial queue pattern. But serial queues only make sense when the dispatched blocks are, themselves, synchronous. (And don't confuse this with dispatch_sync ... we're talking about whether the task inside the block is asynchronous or not, not how you dispatched it to your queue.) But you're dealing with asynchronous methods being called from other asynchronous methods.

处理带有完成处理程序块的方法的基本模式是完全消除串行队列(不需要GCD队列,或者当任务已经异步时非常有用),而只是在您自己的方法中使用完成处理程序块,并在最深层嵌套的块中进行最后一次调用,请调用您自己的完成处理程序.

The basic pattern when dealing with methods that take completion handler blocks, is to eliminate the serial queue altogether (no GCD queue is needed or is useful when the tasks are already asynchronous) and just use completion handler blocks in your own methods, and make the last call in the most deeply nested block call your own completion handler.

例如:

- (void)foo:(void (^)())completion {
    [fileObj setFileInfo:file completion:^(NSError *error) {
        // do some other stuff
        completion();
    }];
}

- (void)bar:(void (^)())completion {
    [fileObj getFileInfo:fileName completion:^(NSError *error) {
        // do some other stuff
        completion();
    }];
}

然后您将其命名为:

[self foo:^{
    [self bar:^{
        // do whatever you want when its all done
    }];
}];

这意味着在完成setFile之前,它不会执行任何getFile内容.

This means that it won't do any of the getFile stuff until the setFile stuff is done.

这样说,我想知道您的setFilegetFile方法在FileObject类自己的方法之上和之外增加了哪些附加值.

Having said this, I wonder what added value your setFile and getFile methods add above and beyond the FileObject classes' own methods.

但是关键是在处理异步方法时,您不能轻松地通过简单的串行GCD队列来协调它们.如果您想为自己本身异步的任务分配类似行为的队列,那么通常考虑使用操作队列(或promise/futures或类似的东西).

But the key is that when dealing with asynchronous methods, you can't easily coordinate them with a simple serial GCD queue. If you want dispatch queue like behavior for tasks that are, themselves, asynchronous, then you'd generally consider using operation queues instead (or promises/futures or something like that).

这篇关于使用dispatch_sync强制执行顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆