Блоки для контура обратных вызовов с пользовательского интерфейса
У меня есть трудоемкий процесс и индикатор прогресса, показывающий пользователю, как далеко все зашло. Поскольку я должен сделать потребляющую вещь в главном потоке, у меня нет возможности просто отправлять обновление в основную очередь между обновлениями. Я должен переключиться на фоновый поток на мгновение, чтобы позволить UI обновиться, прежде чем переключиться обратно и продолжить.
Это то, что у меня есть, но это кажется очень необычным. Есть ли лучший способ сделать " блоки для петли с ответами для пользовательского интерфейса" там, что мне не хватает? Я также не совсем уверен, что это действительно освободит блок в конце, но это другая история.__block NSUInteger i = 0;
__block dispatch_block_t obtainBlock;
obtainBlock = [^{
[self obtainAssetAtIndex:i];
progressView.progress += progressPerFile;
i++;
if (i < assets.count) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
usleep(500);
dispatch_async(dispatch_get_main_queue(), obtainBlock);
});
} else {
[self didImportGroup];
[obtainBlock release];
}
} copy];
dispatch_async(dispatch_get_main_queue(), obtainBlock);
1 ответ:
Слишком сложное мышление. Текущая настройка:
- сделайте одну часть работы
- передача управления фоновому потоку
- сон на заднем плане
- запланируйте следующую часть работы по основному потоку
Что вы хотите сделать:
- сделайте одну часть работы
- запланируйте следующую часть работы
Вот код:
Вам вообще не нужен фоновый поток (особенно когда все, что он делает, это спит).- (void)doWork { if (_assetIndex < assets.count) { [self obtainAssetAtIndex:_assetIndex++]; progressView.progress += progressPerFile; [self performSelector:@selector(doWork) withObject:nil afterDelay:0]; } else { [self didImportGroup]; } }