Grand Central Dispatch,viewWillAppear,viewDidAppear执行混乱的顺序

时间:2011-07-16 11:13:05

标签: ios objective-c grand-central-dispatch viewwillappear viewdidappear

我在我的Tab栏应用程序中使用GCD进行后台下载。

第一步是在-viewWillAppear:中进行一些后台下载(在加载视图之前设置一些基本数据)。

第二步-viewDidAppear:

中后续下载的其余部分

出于某种原因,-viewDidAppear:中的调度块在-viewWillAppear:中的调度块之前被称为

这只在加载应用程序第一次切换到使用GCD背景方法的选项卡后发生一次。切换到另一个选项卡,然后使用GCD背景方法切换回选项卡。第三个(以及所有其余的后续时间)我正在按照预期切换它的工作(首先-viewWillAppear:然后再-viewDidAppear:)。

以下是我的代码(-viewWillAppear:-viewDidAppear:)的摘录:

-viewWillAppear:

- (void)viewWillAppear:(BOOL)animated {
    DLog(@"viewWillAppear method running");

    [super viewWillAppear:animated];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

        [self setDiskCareerIds:[CareersParser idsFrom:@"disk"]];
        [self setDownloadedCareerIds:[CareersParser idsFrom:@"web"]];


        DLog(@"diskCareerIds after being set in viewWillAppear: %@", [self diskCareerIds])
        DLog(@"downloadedCareerIds after being set in viewWillAppear: %@", [self downloadedCareerIds])

        if ([[self downloadedCareerIds] isEqualToArray:[self diskCareerIds]]) {

            DLog(@"viewWillAppear: ids equal, loading careers from disk.");
            self.careers = [CareersParser loadCareersFromDisk];

            dispatch_async(dispatch_get_main_queue(), ^{

                [self.table reloadData];

                [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];


            });
        }

    });

    //[self downloadData];
}

-viewDidAppear:

- (void)viewDidAppear:(BOOL)animated {
    DLog(@"viewDidAppear method running");

    [super viewDidAppear:animated];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

        if (![[self downloadedCareerIds] isEqualToArray:[self diskCareerIds]]) {

            DLog(@"ids not equal, saving careers to disk.");

            dispatch_async(dispatch_get_main_queue(), ^{

                [self showLoadingView];

            });

            [CareersParser saveCareersToDisk];
            self.careers = [CareersParser loadCareersFromDisk];
        }



        dispatch_async(dispatch_get_main_queue(), ^{

            [self.table reloadData];

            [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

            [self removeLoadingView];

        });
    });

    //[self download3];

    //[self downloadData];
}

检查Pastie处的调试日志。

1 个答案:

答案 0 :(得分:4)

好吧,你正在第一个块(在viewWillAppear中调度的那个)中打印该日志消息之后它已经完成了一堆解析,而不是它实际开始执行时。

问题是全局队列是并发队列。因此,即使您首先安排第一个块,但它有时落后于与其同时执行的另一个块也就不足为奇了。

一个简单的答案是创建一个串行队列,然后你将确保第一个块在第二个块执行之前完成。这似乎是你想要的,对吧?