2

У меня есть приложение, которое загружает изображения в кучу мест одновременно, вроде как стиль Instagram.Что может привести к тому, что этот код НЕ разрешит повторный вход в трамплин?

Это установка с NSOperationQueue, которая запускает кучу NSOperation обертки вокруг асинхронного NSURLConnection.

Большинство вопросов, которые начинаются, как этого в «обратные вызовы не вызываются, поскольку вызывающий поток присоединяется прежде чем они вернутся. Это не, что такой вопрос. Я утра получать мои обратные вызовы, как и ожидалось, но я также каким-то образом препятствую тому, чтобы приложение отображалось при нажатии кнопки «Домой». Я всегда думал, что это невозможно заблокировать из-за песочницы, но каким-то образом я это сделал. Нажатие кнопки «домой» во время выполнения операций будет ничего не делать до тех пор, пока они не будут завершены, и в этот момент (20-30 секунд позже) приложение будет правильно фонов.

** NB Это похоже только на одноядерные процессорные устройства. roduce только на моем iPhone 4, но не мой 4S или iPad 3. *

Все еще интересно? Вот моя настройка:

self.uploadQueue = [[NSOperationQueue alloc] init]; 
[self.uploadQueue setMaxConcurrentOperationCount:1]; 
[self.uploadQueue setSuspended:YES]; 

Позже я добавляю операции в очередь, а затем отказываюсь от ее запуска. Вот код из этих NSOperation подклассов:

- (BOOL)isConcurrent { return YES; } 
- (BOOL)isExecuting { return self.executing; } 
- (BOOL)isFinished { return self.finished; } 

- (void)start { 
    // Omitted: check for cancel... 
    // Omitted: check if setup to run 

    [self willChangeValueForKey:@"isExecuting"]; 
    self.executing = YES; 
    [self didChangeValueForKey:@"isExecuting"]; 

    [self.sharer share];  
    CFRunLoopRun(); 
} 


- (void)completeOperation { 
    [self willChangeValueForKey:@"isFinished"]; 
    [self willChangeValueForKey:@"isExecuting"]; 
    self.executing = NO; 
    self.finished = YES; 
    [self didChangeValueForKey:@"isExecuting"]; 
    [self didChangeValueForKey:@"isFinished"]; 
    CFRunLoopStop(CFRunLoopGetCurrent()); 
} 

Метод share устанавливает асинхронный NSURLConnection и запускает его так:

- (void)share { 
    // Omitted: connection setup 
    [NSURLConnection sendAsynchronousRequest:postRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error){ 
     // handle error or success, then call 
     [self.currentOperation completeOperation]; 
    }]; 

Помимо побочного эффекта я пытаюсь решить для , код работает тем, что он делает то, что он должен делать, вызываемые вызовы вызываются, потоки остаются в живых до тех пор, пока они необходимы, а в очереди операций выполняется только определенное количество операций за раз.

Что я пробовал? Я пробовал:

  1. Вызов NSURLConnection на [NSOperationQueue currentQueue]. Это заставило асинхронное соединение не отменить блок.
  2. Принуждение каждого NSOperation к основной нити в методе start. Это не решило проблему, также вызвало некорректный код, и пользовательский интерфейс иногда зависал.
  3. Реализация собственной очереди с изменяемым массивом и GCD, чтобы попасть в нужный поток отправки. Не удалось заставить его работать.
  4. Синхронные NSURLCсоединения в операциях. Я действительно не пытался это сделать, потому что это не вариант для меня. Некоторые из сетевых инфраструктур, таких как SDK для iOS для Facebook, не имеют синхронного варианта.

Приостановка выполнения в течение времени после нажатия кнопки домашнего нажатия, но до выполнения операций не дает ничего интересного. Кажется, что ничего не происходит в основном потоке, ожидая завершения или завершения выполнения блокировки.

Threads 1Threads 2

Am I установка этого вверх, как полный профан? Что здесь происходит и как я могу это исправить?

+0

Просто интересно - вы попробовали запустить его на устройстве с выпуском сборки, не привязанным к отладчику? Интересно, может быть, вы можете продолжать работать, потому что процесс сторожевого таймера не так строг, когда вы используете отладочную сборку. Если это не так, возможно, файл отчета об ошибке с яблоком. –

+0

Я, я пробовал использовать Ad-Hoc с такими же результатами. Это был бета-тестер, который привлек это к моему вниманию. – coneybeare

+0

Я всегда обнаружил, что получение «параллельных» подклассов NSOperation выполняется правильно, чтобы быть подверженным ошибкам. Собственный пользователь [QA1712] (http://developer.apple.com/library/ios/#qa/qa1712/_index.html) описывает это как «довольно сложное». –

ответ

0

EDIT:

Оказывается, все это сетевой материал был отвлекающим маневром. Это были некоторые петлевые CAAnimations, которые каким-то образом препятствовали возврату на трамплин.

Оригинальные Догадки:

Мое предположение: вы не должны называть в вашем методе запуска CFRunLoopRun; ожидается, что метод запуска параллельной операции будет возвращен до завершения операции и завершения позже. Вероятно, вы держитесь за блокировку GCD (поток?), Что системе нужно отправлять другие задачи.

Если вам нужно монополизировать нить через CFRunLoopRun, вы должны начать свою собственную нить в start, а затем вернуться. Я думаю, было бы проще, но просто не использовать NSOperation и не запускать ваши (уже асинхронные) url-соединения из основного потока, сохраняя массив вещей, чтобы поделиться, когда каждый из них закончен.

На самом деле, я думаю, проблема в CFRunLoopStop(CFRunLoopGetCurrent()): вы используете это на главной линии , так что вы останавливаете главный цикл запуска!

+0

Хм, просто попробовал это так ... все еще не позволяет приложению уйти. Я полностью удалил nsoperations и позвонил из основного потока. – coneybeare

+0

Вы все еще можете 'CFRunLoopRun'? Я также собираюсь добавить еще одну идею. –

+0

Нет, в операции была операция runloop, которую я сейчас не использую. Я добавил переключатель в своем приложении, чтобы отключить его, пока я отлаживаю. Теперь это всего лишь массив, который запускает асинхронные соединения 1 за раз, уволяя следующий один из предыдущих блоков завершения. – coneybeare

Смежные вопросы