0

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

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

第二步是把剩下的后台下载进去-viewDidAppear:

出于某种原因,调度块 in 在调度块 in之前-viewDidAppear:调用。-viewWillAppear:

这只会在第一次加载应用程序后使用 GCD 后台方法切换到选项卡后发生一次。切换到另一个选项卡,然后使用 GCD 后台方法切换回选项卡。第三次(以及随后的所有其他时间)我切换回来的时候它按预期工作(-viewWillAppear:先开火然后再开火-viewDidAppear:)。

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

-viewWill出现:

- (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的调试日志。

4

1 回答 1

4

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

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

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

于 2011-07-16T15:29:40.750 回答