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 · 6726 views
    This topic created in 4044 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
    hustlzp
    OP
    Oct 15, 2015❤️1
    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
    yellowV2ex
    Oct 15, 2015
    2
    简单点的做法,搞个静态变量记录一下?
    arkilis
    arkilis
    Oct 15, 2015❤️1
    3
    or you can use NSOperation depends
    hustlzp
    hustlzp
    OP
    Oct 15, 2015
    4
    @yellowV2ex 每执行完就+1 ,然后观察这个数,当达到预定值时就表示所有都执行完毕?恩,这样应该可以。
    hustlzp
    hustlzp
    OP
    Oct 15, 2015
    5
    @arkilis 3Q ,查了下,确实可以达到同样的效果。
    jesse_luo
    jesse_luo
    Oct 15, 2015
    6
    dispatch_group 应该是最简单的吧
    matsuijurina
    matsuijurina
    Oct 15, 2015 via iPad❤️1
    7
    如果你习惯了 promise...then...可以试一下 promisekit 这个库
    hustlzp
    hustlzp
    OP
    Oct 15, 2015
    8
    @jesse_luo 恩,目前我就找到这一种...

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

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