iOS - Grand Central Dispatch получает значение из блока в dispatch_async - PullRequest
1 голос
/ 13 июля 2011

Я использую приведенный ниже код для загрузки некоторых данных из Интернета.Прав ли я, что мне нужно сохранить данные, как я сделал?Также оператор NSLog изнутри блока показывает, что массив заполнен, но когда я запускаю NSLog вне блока, массивы отображаются как (null).Как сохранить данные вне метода dispatch_async?

    __block NSArray *downloadedCareerIds;
    __block NSArray *diskCareerIds;

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        /* Download stuff */

        downloadedCareerIds = [[CareersParser idsFrom:@"web"] retain];
        diskCareerIds = [[CareersParser idsFrom:@"disk"] retain];

        DLog(@"downloadedCareerIds: %@", downloadedCareerIds);

        DLog(@"diskCareerIds: %@", diskCareerIds);

    });


    DLog(@"downloadedCareerIds: %@", downloadedCareerIds);

    DLog(@"diskCareerIds: %@", diskCareerIds);

Ответы [ 2 ]

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

Идея dispatch_async состоит в том, что вы даете ему блок кода для асинхронного выполнения, поэтому отказываетесь от контроля над тем, когда этот код будет выполнен.Вызов dispatch_async возвращается после того, как блок был поставлен в очередь, а НЕ после завершения выполнения блока (отсюда и асинхронность).Поэтому операторы log внутри блока, который вы передаете dispatch_async, будут выполняться почти всегда после операторов log ниже вашего вызова dispatch_async.

2 голосов
/ 13 июля 2011

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

Если вы хотите воздействовать на данные в том же методе, вам придется либо отправить блокировку dispatch_sync, которая не имеет смысла, либо вы можете вызвать методы внутри блока.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    ....

    [self doStuffWithTheArrays];
});

Как только блок будет выполнен, объекты будут доступны при условии, что они являются переменными экземпляра, или вы потеряете ссылки.

...