Я читал следующую документацию Apple по блоку завершения в очередях отправки, и у меня возникли проблемы с пониманием ее части. В документе упоминается, что «для предотвращения преждевременного освобождения очереди крайне важно сохранить эту очередь первоначально и освободить ее после отправки блока завершения». Это противоречит моему пониманию того, что блок сохраняет все переменные в своем закрытии, что упоминается в Руководстве по программированию блока.
Что мне здесь не хватает? Фрагмент из документа вставлен ниже:
Блок завершения - это просто еще один фрагмент кода, который вы отправляете в очередь в конце своей исходной задачи. Код вызова обычно предоставляет блок завершения в качестве параметра при запуске задачи. Все, что должен сделать код задачи, это отправить указанный блок или функцию в указанную очередь, когда он завершит свою работу.
В листинге 3-4 показана функция усреднения, реализованная с использованием блоков. Последние два параметра функции усреднения позволяют вызывающей стороне указывать очередь и блок для использования при сообщении результатов. После того, как функция усреднения вычисляет свое значение, она передает результаты в указанный блок и отправляет его в очередь. Чтобы предотвратить преждевременное освобождение очереди, важно сначала сохранить эту очередь и освободить ее после отправки блока завершения.
Перечисление 3-4, Выполняющее обратный вызов завершения после задачи
void average_async(int *data, size_t len, dispatch_queue_t queue, void (^block)(int))
{
// Retain the queue provided by the user to make
// sure it does not disappear before the completion
// block can be called.
dispatch_retain(queue);
// Do the work on the default concurrent queue and then
// call the user-provided block with the results.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
int avg = average(data, len);
dispatch_async(queue, ^{ block(avg);});
// Release the user-provided queue when done
dispatch_release(queue);
});
}