В моем приложении у меня есть три интернет-операции, которые запускаются сразу. Они не зависят друг от друга, поэтому я запускаю каждый из них в фоновом потоке. Каждый из них должен быть завершен, хотя до того, как мое приложение сможет перейти к обработчику завершения.Приложение iOS ведет себя по-разному с помощью схемы отладки vs
Метод, который запускает каждый из трех, принимает в качестве параметра блок-код, который выполняет функции обработчика завершения. Этот метод также имеет локальную переменную, называемую internetOperationsRemaining, которую я установил равной 3, прежде чем я начну каждую из трех интернет-операций.
Когда каждый из интернет-операций завершен, я уменьшаю количество интернет-операций. На основном потоке. Это приводит к тому, что internetOperationsRemaining == 0, когда все они завершены.
Чтобы прослушать это условие, я запускаю жесткий цикл в другом фоновом потоке, который просто зацикливает на себя, ожидая, пока internetOperationsRemaining равняется 0. Как только это произойдет, я вызываю обработчик завершения, который был передан как параметр, как описано выше.
//Spawn a background thread and loop in it until
//allInternetOperationComplete == true.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while(internetOperationsRemaining > 0)
{
//Just spins in here on a background thread waiting
//on the internet to finish.
}
//Now that internetOperationsRemaining == 0, kill the NSURL session
//and call the completion handler on the main thread.
dispatch_async(dispatch_get_main_queue(), ^{
[session finishTasksAndInvalidate];
completionHandler();
});
});
странное поведение, которое я вижу в том, что приложение работает отлично, если я отладка установлена в схеме, и это не, если я выбран релиз. Он просто никогда не выходит из цикла while.
Если я вставляю какой-то тривиальный код в цикл while, чтобы немного замедлить работу, он отлично работает как для отладки, так и для выпуска.
while(internetOperationsRemaining > 0)
{
//Just spins in here on a background thread waiting
//on the internet to finish.
int i=0;
++i;
}
Я затрудняюсь объяснить это поведение. Тесная петля находится в фоновом потоке, поэтому приложение будет реагировать на ввод пользователя, как и следовало ожидать. Я понимаю, что в схеме выпуска представлены оптимизации, но я удивлен, что это действительно изменило поведение приложений.
Спасибо за ответ! Мне не понравилось, что круглая петля тоже вращалась, но не знал о NSOperation. Потребовалось около 5 минут чтения, чтобы понять, что это дает именно то, что я пытался сделать. Я буду переписывать этот раздел кода завтра, используя ваше предложение, и если он исправит проблему (я подозреваю, что это будет), я обязательно выберу ваш ответ в качестве ответа. Еще раз спасибо! – Scooter
Метод вызывает то, что я жду, чтобы завершить каждый вызов методов NSURLSession, которые сами являются асинхронными с их собственными обработчиками завершения. Простое размещение этих методов в очереди NSOperations оставляет мне мою первоначальную проблему. Вызывается метод NSURLSession, завершается NSBlockOperation, и все это происходит до того, как методы NSURLSession завершены. Я просматриваю пользовательский подкласс NSOperation, чтобы увидеть, могу ли я заставить его работать таким образом. – Scooter
Выяснилось, что это сложнее, чем я думал ... – Scooter