Айсинхронные методы, блоки и GCD, имеющие проблемы с пониманием - PullRequest
1 голос
/ 14 февраля 2012

У меня есть следующий фрагмент кода, который использует библиотеку ALAssets для хранения массива фотоальбомов пользователей, чтобы он мог заполнить их в таблице, такой как приложение для фотографий:

- (void) loadAlbums
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [[self activityIndicator] startAnimating];

    [[self library] enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop)
    {
        if (group == nil)
        {
            [[self activityIndicator] stopAnimating]; 
            [[self tableView] reloadData];

            return;
        }

        [[self albums] addObject:group];
    }
    failureBlock:^(NSError *error) 
    {
        UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[NSString stringWithFormat:@"Album Error: %@", [error description]] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        [alert release];
    }];

    [pool release];
}

Насколько я понимаю, enumerateGroupsWithTypes - это асинхронный метод, который означает, что он работает в своем собственном потоке. Однако параметр блока выполняется в основном потоке. С кодом вверху у меня проблема с индикатором активности. Когда viewcontroller с этим методом запускается в первый раз, activityindicator работает нормально, однако, если я вытолкну viewcontroller из стека (т. Е. Нажму кнопку возврата) и перезагрузлю его снова, индикатор активности не появится ( несмотря на то, что я играю с isHidden и т. д.). Итак, у меня есть несколько вопросов:

1) Кто-нибудь может понять, в чем проблема с индикатором активности?

2) Помимо использования [NSThread sleepWithDuration] и NSTimer, как лучше всего имитировать медленное время загрузки без создания фотоальбома с кучей фотографий?

3) Если загрузка фотографий займет некоторое время, будет ли заблокирован пользовательский интерфейс моего приложения или пользователь по-прежнему сможет с ним взаимодействовать? Поскольку он работает в отдельном потоке, похоже, что должен, но я не совсем уверен.

ОБНОВЛЕНИЕ: Есть идеи или ресурсы о том, как стать лучше с этим? Я читал нить программистов Apple и парней по параллелизму и смотрел много видеороликов WWDC, но мне все еще трудно понять, как справляться с такими простыми ситуациями, как эта, когда я просто пытаюсь не блокировать пользовательский интерфейс от пользователя.

1 Ответ

3 голосов
/ 14 февраля 2012

Насколько я понимаю, enumerateGroupsWithTypes - это асинхронный метод, который означает, что он работает в своем собственном потоке.

"Асинхронный" не означает "работает в своем собственном потоке""Есть несколько способов быть асинхронными в iOS.Одним из наиболее распространенных является использование цикла выполнения.Это не означает, что этот метод не генерирует поток;это может.Но нет никаких оснований предполагать, что это так, и если это так, то это частная реализация.Как вы говорите, ваш блок работает в главном потоке, и это единственное, что действительно должно вас здесь беспокоить.

Судя по описанному вами признаку, я сомневаюсь, что он как-то связан с этим кодом.Это больше похоже на ошибку в вашем представлении загрузки кода.Я бы проверял подпрограммы loadView, viewDidLoad, initWithFrame:, awakeFromNib, viewWillAppear: и viewDidAppear:.По всей вероятности, вы создаете свой индикатор прогресса не в том месте, или не можете вставить его в иерархию представлений, или удалите его из иерархии представлений.

Что касается имитации медленного времени загрузки, я бы порекомендовал "большое количество картинок "подход.Вы должны иметь возможность генерировать большое количество изображений программно (вы даже можете просто дублировать одно и то же изображение снова и снова), так что это не должно быть слишком плохо.Немного раздражает, если это ваше личное устройство, но такова природа разработки.

...