На самом деле запросы не ожидают, пока все они не будут отправлены.Когда все работает правильно, каждый обратный вызов происходит, когда соответствующий запрос завершается, и не имеет смысла, чтобы это происходило раньше, потому что обратный вызов предоставляет ответ от сервера (который невозможно вернуть до тех пор, пока запрос не будет выполнен).был полностью разослан).
Проблема здесь в том, что вы полностью забиваете сеанс, запуская слишком много задач одновременно.В NSURLSession есть известная ошибка, из-за которой он начинает разваливаться, когда вы создаете большое количество задач в одном сеансе за раз.Когда вы получаете слишком много задач в сеансе, IIRC, сеанс полностью прекращает обратный вызов, и в основном сеанс становится непригодным для использования.(Есть еще один вопрос переполнения стека, в котором это обсуждалось пару лет назад, хотя я не могу найти его прямо сейчас.)
И поскольку задачи никогда не выполняются, ваше приложение теряет всепамяти, которую вы используете для данных тела, что означает, что ваше приложение просто выделяет все больше и больше памяти, пока оно не будет удалено.
Единственный способ решить эту проблему - перестать добавлять все запросы в сеанс.все сразу.Сначала запустите несколько заданий (максимум для восьми частей или около того), а затем дождитесь отправки следующей части, пока одна из предыдущих частей не завершится или не выполнится ошибка.Этот подход не только предотвратит блокирование NSURLSession, но также запретит выделять безумный объем памяти для хранения всех объектов NSData тела запроса, которые в настоящее время все одновременно находятся в оперативной памяти.
Я предлагаю сохранить NSMutableArray объекта NSNumber, представляющего каждый неотправленный кусок.Таким образом, вы знаете, что еще нужно отправить, и вы можете просто вернуться к 8 и извлечь первые 8 номеров и отправить куски с этими номерами.Когда запрос завершится успешно, извлеките следующий номер из массива и отправьте кусок с этим номером.
Кроме того, вам не следует останавливаться после определенного числа повторных попыток.Вместо этого при сбое запроса проверьте сбой, чтобы решить, следует ли повторить попытку (сбой сети) или отказаться (ошибка сервера).Затем используйте функцию доступности, чтобы дождаться подходящего времени, чтобы повторить попытку, и повторите попытку, когда появится сообщение о доступности хоста назначения.Отмените загрузку, только если пользователь явно попросит вас отменить загрузку, нажав кнопку отмены или аналогичное.Если пользователь просит отменить загрузку, разрушите структуру данных, чтобы не запускать новые запросы, а затем аннулируйте сеанс URL.