iOS — Grand Central Dispatch получает значение из блока в dispatch_async

Я использую приведенный ниже код для загрузки некоторых данных из Интернета. Я прав, что мне нужно сохранить данные, как я сделал? Также оператор 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);

person Peter Warbo    schedule 13.07.2011    source источник


Ответы (2)


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

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

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

    [self doStuffWithTheArrays];
});

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

person Deepak Danduprolu    schedule 13.07.2011
comment
Спасибо! Знаете ли вы, почему метод -doStuffWithTheArrays должен быть объявлен в файле интерфейса, когда я обращаюсь к методу в том же классе? Блоки не могут видеть собственные определенные методы? - person Peter Warbo; 14.07.2011

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

person Paul Tiarks    schedule 13.07.2011