Итак, после изучения блоков завершения в то время, мне нравится использовать блоки завершения. Мне нравится закрытие, и мне нравится возможность передавать практически все, что захочу.о enqueuing с использованием блоков завершения
Как кто-то, кто является новичком в программировании ниток, я держался подальше от GCD и NSOperation, но в последнее время мне пришлось программировать асинхронное обновление данных Core Data, и я начинаю сомневаться в моем «завершении» блокировать все время ".
Итак, вот один из примеров того, что я задаю себе вопрос: у меня есть серия потенциально довольно больших данных (изображений, звука, видео, что у вас есть) для загрузки на сервер где-нибудь. Метаданные для этих данных хранятся в Core Data, и у меня есть метка времени, которую я использую, чтобы решить, какие объекты должны быть загружены. Все эти загрузки должны выполняться последовательно.
То, что я закодированы это по существу в основном только функция с блоком завершения в нем, что есть вызов себе в конце блока, как это:
(void)uploadAllAsynchronously {
... // First figure out what to upload based on core data
// Here comes the completion block in question
void(^blk)(BOOL) = ^(BOOL)uploadSuccess {
... // if upload successful, update core data to mark what has been uploaded
[self uploadAllAsynchronously]; // Recursively calls the function that contains this block. I actually have a weak self, or if that fails to break a retain cycle, I should be able to pass in a NSManagedObjectContext as an argument.
}
[NSURLConnection sendAsynchronousRequest:... queue:... completionHandler:blk];
}
Это должно работать, правильно ? Есть ли что-то здесь, что совершенно опасно, что я предлагаю использовать GCD и обрабатывать свою собственную очередь? Я спрашиваю об этом, потому что у меня есть некоторые проблемы прямо сейчас, возможно, с данными в нем появятся разные потоки, которые не будут правильно обновляться из-за асинхронных вызовов, хотя не уверены, какая часть моего кода является виновником.
Заранее спасибо.
Имейте в виду, что обработчики завершения обычно не работают на фоновом потоке. Обычно (включая '[NSURLConnection sendAsynchronousRequest: queue: completionHandler:]') блок завершения выполняется в основном потоке. Поэтому вам не нужно беспокоиться о безопасности потоков. Если основной поток занят, когда фоновый поток завершает загрузку, он будет ждать, пока основной поток не будет простаивать до выполнения блока завершения. –
Я узнал, что есть один случай, когда вложенные блоки завершения будут проблематичными и могут вызвать взаимоблокировки: http://www.cocoawithlove.com/2010/06/avoiding-deadlocks-and-latency-in.html – Victor