iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
hustlzp
V2EX  ›  iDev

Objective-C 中,如何等待多个异步函数完成后,再执行某段代码?

  •  1
     
  •   hustlzp · Oct 15, 2015 · 6269 views
    This topic created in 3870 days ago, the information mentioned may be changed or developed.

    有个 API 如下:

    + (void)updateByUser:(ALUser *)user completion:(void (^)(void))completion
    {
        AVQuery *query = [AVQuery queryWithClassName:@"Feed"];
        query.limit = 15;
        [query orderByDescending:@"createdAt"];
        [query whereKey:@"user" equalTo:[AVObject objectWithoutDataWithClassName:@"User" objectId:user.objectId]];
        [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
            if (!error) {
                for (AVObject *feed in objects) {
                    [self saveFeed:feed];
                }
    
                if (completion) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        completion();
                    });
                }
            } else {
                NSLog(@"Error: %@ %@", error, [error userInfo]);
            }
        }];
    }
    

    一次调用如下:

    [ALFeed updateByUser:user completion:^{
        [self.tableView reloadData];
    }];
    

    但如果需要多次调用后再执行回调:

    for (ALUser *user in users) {
        [ALFeed updateByUser:user completion:^{
    
        }];
    }
    

    如何在所有 updateByUser:completion: 执行完后,再执行 [self.tableView reloadData];

    JavaScript 可以用 promise 库(比如 bluebird )解决这样的问题:

    var files = [];
    for (var i = 0; i < 100; ++i) {
        files.push(fs.writeFileAsync("file-" + i + ".txt", "", "utf-8"));
    }
    Promise.all(files).then(function() {
        console.log("all the files were created");
    });
    

    但在 Objective-C 中,如何解决?

    22 replies    2015-10-15 20:09:22 +08:00
    hustlzp
        1
    hustlzp  
    OP
       Oct 15, 2015   ❤️ 1
    已解决,原来 GCD 中有个 dispatch_group 是专门解决这种问题的...

    看来得找个时间专门学习 GCD ...

    ```objc
    dispatch_group_t group = dispatch_group_create();

    for (ALUser *user in self.users) {
    dispatch_group_enter(group);
    [ALFeed updateByUser:user completion:^{
    dispatch_group_leave(group);
    }];
    }

    dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    [self.tableView reloadData];
    });
    ```

    参考:

    * [Waiting on Groups of Queued Tasks]( https://developer.apple.com/library/ios/documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html#//apple_ref/doc/uid/TP40008091-CH102-SW25)
    * [Using dispatch groups to wait for multiple web services]( http://commandshift.co.uk/blog/2014/03/19/using-dispatch-groups-to-wait-for-multiple-web-services/)。
    yellowV2ex
        2
    yellowV2ex  
       Oct 15, 2015
    简单点的做法,搞个静态变量记录一下?
    arkilis
        3
    arkilis  
       Oct 15, 2015   ❤️ 1
    or you can use NSOperation depends
    hustlzp
        4
    hustlzp  
    OP
       Oct 15, 2015
    @yellowV2ex 每执行完就+1 ,然后观察这个数,当达到预定值时就表示所有都执行完毕?恩,这样应该可以。
    hustlzp
        5
    hustlzp  
    OP
       Oct 15, 2015
    @arkilis 3Q ,查了下,确实可以达到同样的效果。
    jesse_luo
        6
    jesse_luo  
       Oct 15, 2015
    dispatch_group 应该是最简单的吧
    matsuijurina
        7
    matsuijurina  
       Oct 15, 2015 via iPad   ❤️ 1
    如果你习惯了 promise...then...可以试一下 promisekit 这个库
    hustlzp
        8
    hustlzp  
    OP
       Oct 15, 2015
    @jesse_luo 恩,目前我就找到这一种...

    麻烦问下其他复杂一点的方法有?
    hustlzp
        9
    hustlzp  
    OP
       Oct 15, 2015
    @matsuijurina 。。。 promise 无处不在啊。。。
    onevcat
        10
    onevcat  
       Oct 15, 2015   ❤️ 2
    -.- ReactiveCocoa , combineLatest

    好吧,直接 dispatch_group 多好..
    Elethom
        11
    Elethom  
       Oct 15, 2015 via iPhone
    @onevcat
    我也先想到 RAC 了。
    chaoxn
        12
    chaoxn  
       Oct 15, 2015
    喵大~
    ibcker
        13
    ibcker  
       Oct 15, 2015   ❤️ 1
    dispatch_group or 信号量
    fhefh
        14
    fhefh  
       Oct 15, 2015
    记录下 嘿嘿
    rannie
        15
    rannie  
       Oct 15, 2015   ❤️ 1
    dipatch_group 或者 rac signal
    hustlzp
        16
    hustlzp  
    OP
       Oct 15, 2015
    @onevcat ^_^
    yongSir
        17
    yongSir  
       Oct 15, 2015
    2 个方法
    用调度组
    或者
    在 operation 中使用 barrier block
    loveuqian
        18
    loveuqian  
       Oct 15, 2015 via iPhone
    线程添加依赖也可以嘛?
    LINAICAI
        19
    LINAICAI  
       Oct 15, 2015
    NSOpention 依赖也可以
    newtonisaac
        20
    newtonisaac  
       Oct 15, 2015
    promise when
    hustlzp
        21
    hustlzp  
    OP
       Oct 15, 2015
    @loveuqian 可以的
    @LINAICAI
    jesse_luo
        22
    jesse_luo  
       Oct 15, 2015
    用 semaphore 硬卡……
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1002 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 83ms · UTC 22:19 · PVG 06:19 · LAX 15:19 · JFK 18:19
    ♥ Do have faith in what you're doing.