Великая Центральная диспетчеризация, viewWillAppear, viewDidAppear порядок выполнения путаницы - PullRequest
0 голосов
/ 16 июля 2011

Я использую GCD для фоновой загрузки в приложении Tab Bar.

Первый шаг - выполнить фоновую загрузку в -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 Ответ

4 голосов
/ 16 июля 2011

Что ж, вы печатаете это сообщение журнала в том первом блоке (который запланирован в viewWillAppear :) после он выполнил кучу разборов, а не когда он фактически начинает выполняться.

Дело в том, что глобальная очередь - это параллельная очередь. Поэтому, даже если вы сначала планируете этот первый блок, неудивительно, что он иногда отстает от другого блока, который выполняется одновременно с ним.

Один простой ответ - создать последовательную очередь, и тогда вы будете уверены, что первый блок завершится до того, как будет выполнен второй. Кажется, это то, что вы хотите, верно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...