Выйти из приложения во время работы цикла for - PullRequest
0 голосов
/ 04 февраля 2012

В моем приложении у меня есть tableView, заполненный содержимым с сервера.Для загрузки этого содержимого я использую NSURLConnection и создаю NSMutableArray (tableItems) для хранения и управления адресами изображений, которые я хочу использовать.

В connectionDidFinishLoading после заполнения tableItems есть этот цикл for:

for (int i = 0; i < [tableItems count]; i++) {

        // HERE I CHECK IF THE IMAGE I'M LOOKING FOR IS ALREADY ON DISK
        NSString *pathToCheckImage = [NSString stringWithFormat:@"%@/%@.png", pathToPreviews, [tableItems objectAtIndex:i]];
        NSData *dataOfCheckImage = [NSData dataWithContentsOfFile:pathToCheckImage];
        UIImage *checkImage = [UIImage imageWithData:dataOfCheckImage];

        NSString *pathToImage;
        UIImage *image;
        if (checkImage != nil) {
            // THE IMAGE IS ALREADY ON DISK SO I GET IT FROM TEMP FOLDER
            image = checkImage;
        } else {

            // THE IMAGE IS NEW SO I HAVE TO GET THE IMAGE FROM THE SERVER
            pathToImage = [NSString stringWithFormat:@"http://www.SERVER.com/SERVER_PATH/%@.png", [tableItems objectAtIndex:i]];

            NSURL *url = [NSURL URLWithString:pathToImage];
            NSData *data = [NSData dataWithContentsOfURL:url];
            image = [UIImage imageWithData:data];

            // AND SAVE IT ON DISK
            NSString *path = [NSString stringWithFormat:@"%@/%@.png", pathToPreviews, [tableItems objectAtIndex:i]];
            [self cacheImageOnDisk:image withPath:path];
        }

        if (image != nil) {
            [arrayOfImages addObject:image];
        }

}

Этот код работает, даже если, в зависимости от количества и размера изображений, которые мне нужно загрузить с сервера, выполнение этой задачи может занять 1 или 2 минуты.

Проблема в том, что если пользователь завершает работу (нажатие кнопки «Домой») во время выполнения цикла for, он продолжает выполнять свою задачу до конца, даже если ему требуется 1 минута для его завершения.

Во время этогопериод повторного запуска приложения неизбежно приводит к сбою при запуске.

Я пытался остановить этот цикл for при выходе, но applicationDidEnterBackground, applicationWillResignActive и applicationWillTerminate не вызываются, пока цикл for не завершит свою задачу.*

Я пытался установить "приложение не работает в фоновом режиме", но ничего не изменилось.

Любое предложение будет по достоинству оценено.

Ответы [ 2 ]

4 голосов
/ 04 февраля 2012

Вы не должны загружать изображения в основной теме. Приложение не будет отзывчивым. Grand Central Dispatch - это простой способ выполнить эти задачи.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSUInteger count = [tableItems count];
    for (int i = 0; i < count; i++) {
        // TODO: check if app didResignActive and break

        UIImage *image = ... // get image from disk or network

        // Add the image to the array on the main thread to avoid any threading issues
        dispatch_sync(dispatch_get_main_queue(), ^{
            [arrayOfImages addObject:image];
        });
    }
});
1 голос
/ 04 февраля 2012

Вам нужно либо обработать ваш цикл из основного потока (очень легко ошибиться), либо разбить вашу работу на куски (намного проще). Попробуйте извлечь ваш цикл в отдельный метод, который запускает его 10 раз, а затем запланирует другой запуск с помощью [... executeSelector: @selector (myMethod) afterDelay: 0]; Это даст runloop возможность циклически обрабатывать события (например, quit) каждые 10 итераций.

Потоки (будь то старыми способами или более новым dispatch_async) все же обеспечат вам лучшую отзывчивость, поэтому, если вы хотите это сделать, я рекомендую следующее:

Не делиться данными между фоновым потоком и основным потоком, пока он работает.

Создайте свой фоновый поток, выполните всю работу с локальным состоянием, к которому нет доступа, и отправьте обратно в основной поток с вашим законченным массивом. Любое общее состояние может очень усложнить вашу жизнь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...