enumerateGroupsWithTypes не будет выполнять блоки при опросе в основном потоке - PullRequest
1 голос
/ 20 июня 2011

В iOS 4.x я пытаюсь перечислить все фотографии на устройстве и, когда это будет завершено, обработать этот список далее в том же методе.

Поскольку блоки enumerateGroupsWithTypes работают асинхронно надругой поток, и я не могу видеть, как не допустить продолжения выполнения основного потока, мое решение не допустить, чтобы дальнейшая обработка начиналась до готовности, это опросить массив фотографий, которые я собираю, до тех пор, пока не обнаружит, что он завершил заполнение включением.объекта NSNull в конце.

В iOS 4.0 все работает нормально - опрос продолжается, поскольку другой поток перечисляет фотографии, а затем выполнение продолжается в главном потоке, когда это делается.В iOS 4.1+ опрос - это то, как мешает другому потоку выполнить любой из его блоков, так что опрос застревает в бесконечном цикле.

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

Бонусные баллы: почему мой подход к опросу работает на 4.0, а не на 4.1 +?

NSMutableArray *photos = [NSMutableArray new];

void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
    if(result != NULL) {
        [photos addObject:result];
    }
};
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
    if(group != nil)
        [group enumerateAssetsUsingBlock:assetEnumerator];
    else
        [photos addObject:[NSNull null]];
};

ALAssetsLibrary *library = [ALAssetsLibrary new];

[library enumerateGroupsWithTypes:ALAssetsGroupAll
                       usingBlock:assetGroupEnumerator
                     failureBlock:^(NSError *error) {
                         NSLog(@"%@", error);
                     }];

// keep polling until the photos have all been enumerated
// (NSNull is the last 'photo' added)
while (![photos count] || ![[photos objectAtIndex:[photos count]-1] isEqual:[NSNull null]]);

// ... further processing ...

1 Ответ

1 голос
/ 20 июня 2011

Лучший способ состоит в том, чтобы ваш блок запускался для дальнейшей обработки (например, с использованием performSelectorOnMainThread:withObject:waitUntilDone:), а не для опроса основного потока.

Не могу точно сказать, почему он работает в 4.0 и не работает в 4.1. Возможно, что в 4.1 он больше не является асинхронным в некоторых случаях (например, когда пользователю не нужно запрашивать) или что в 4.1 он ожидает обратного вызова в главном потоке, прежде чем запустить фоновую задачу, или в вашей 4.1 Экземпляр устройства или симулятора пытается получить разрешение (и вешает трубку, так как у вас заблокирован основной цикл выполнения) и завершится сбоем в версии 4.0, если вы еще не авторизовали его для доступа к библиотеке фотографий в своем предыдущем тестировании.

...