OC 中异步顺序加载用法 dispatch_semaphore

实际开发过程中,有可能会用到顺序加载异步的需求,比如先掉A接口,直到A接口调用完成,在调用B接口,以此类推C接口...

当然一两个接口这样写没问题,如果这样的接口多了,或者其他情况就不多说了。

解决办法:dispatch_semaphore

dispatch_semaphore是GCD用来同步的一种方式,与他相关的共有三个函数,分别是dispatch_semaphore_create,dispatch_semaphore_signal,dispatch_semaphore_wait。

实例:

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

/// 创建异步线程

dispatch_async(dispatch_get_global_queue(0, 0), ^{

/// 第一步 

   [self logWithBlock:^(NSString *name) {

        NSLog(@"1%@",name);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            dispatch_semaphore_signal(semaphore);

        });       

    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

/// 第二部

    [self logWithBlock:^(NSString *name) {

        NSLog(@"2%@",name);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            dispatch_semaphore_signal(semaphore);

        });

    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

/// 第三步

    [self logWithBlock:^(NSString *name) {

        NSLog(@"3%@",name);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            dispatch_semaphore_signal(semaphore);

        });

    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

/// 第四步

    [self logWithBlock:^(NSString *name) {

        NSLog(@"4%@",name);

        dispatch_semaphore_signal(semaphore);

    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    NSLog(@"完毕");

});

输出

解释:

(1)dispatch_semaphore_create的声明为:

  dispatch_semaphore_t  dispatch_semaphore_create(long value);

  传入的参数为long,输出一个dispatch_semaphore_t类型且值为value的信号量。

  值得注意的是,这里的传入的参数value必须大于或等于0,否则dispatch_semaphore_create会返回NULL。

  (关于信号量,我就不在这里累述了,网上很多介绍这个的。我们这里主要讲一下dispatch_semaphore这三个函数的用法)。


(2)dispatch_semaphore_signal的声明为:

  long dispatch_semaphore_signal(dispatch_semaphore_t dsema)

  这个函数会使传入的信号量dsema的值加1;(至于返回值,待会儿再讲)


 (3) dispatch_semaphore_wait的声明为:

  long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);

  这个函数会使传入的信号量dsema的值减1;

  这个函数的作用是这样的,如果dsema信号量的值大于0,该函数所处线程就继续执行下面的语句,并且将信号量的值减1;

  如果desema的值为0,那么这个函数就阻塞当前线程等待timeout(注意timeout的类型为dispatch_time_t,

  不能直接传入整形或float型数),如果等待的期间desema的值被dispatch_semaphore_signal函数加1了,

  且该函数(即dispatch_semaphore_wait)所处线程获得了信号量,那么就继续向下执行并将信号量减1。

  如果等待期间没有获取到信号量或者信号量的值一直为0,那么等到timeout时,其所处线程自动执行其后语句。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容