2013-04-14 2 views
0

Я конвертирую свое приложение IPhone в IPad, и у меня возникла проблема с преобразованием. У меня есть фоновый поток, который создает несколько эскизов.Задержка на IPad при вызове из фонового потока

Проблема заключается в том, что приложение перемещается по всему массиву и выводит все элементы, но только последний элемент, по-видимому, загружается с текстом UIButton. Задержка 5-15 секунд до того, как все предыдущие кнопки отображают текст.

UIImage *tmp = [self thumbnailImage:[effect objectAtIndex:0] thumbnailType:@"category"]; 

for (id effect in effectArray) { 

    UIImage *tmp = [self thumbnailImage:[effect objectAtIndex:0] thumbnailType:@"category"]; 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     UIView *effectView = [[UIView alloc] initWithFrame:CGRectMake(item_x_axis, current_row_height, item_width, item_height)]; 

     UIImageView *imagepreview = [[UIImageView alloc] init]; 
     [imagepreview setFrame:CGRectMake(20, 20, 100, 100)]; 
     [imagepreview setImage:tmp]; 
     imagepreview.contentMode = UIViewContentModeScaleAspectFit; 
     imagepreview.layer.shadowColor = [UIColor blackColor].CGColor; 
     imagepreview.layer.shadowOffset = CGSizeMake(0, 1); 
     imagepreview.layer.shadowOpacity = 1; 
     imagepreview.layer.shadowRadius = 2.0; 
     imagepreview.clipsToBounds = NO; 
     [effectView addSubview:imagepreview]; 

     if([[effect objectAtIndex:3] isEqualToString:@"iap"]){ 

      UIImageView *buttonPlus = [[UIImageView alloc] init]; 
      [buttonPlus setFrame:CGRectMake(54, 66, 23, 23)]; 
      [buttonPlus setImage:[UIImage imageNamed:@"ButtonPlus.png"]]; 
      [effectView addSubview:buttonPlus]; 

     } 

     UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
     [button addTarget:self action:NSSelectorFromString([effect objectAtIndex:1]) forControlEvents:UIControlEventTouchDown]; 
     [button setTitle:[effect objectAtIndex:2] forState:UIControlStateNormal]; 
     button.frame = CGRectMake(0, 0, item_width, item_height); 
     button.titleLabel.font = [UIFont systemFontOfSize:11]; 
     [button setTitleShadowColor:[UIColor blackColor] forState:UIControlStateNormal]; 
     [button.titleLabel setShadowOffset:CGSizeMake(1.0f, 1.0f)]; 
     [button setTitleEdgeInsets:UIEdgeInsetsMake(120, 0, 0.0, 0.0)]; 
     [effectView addSubview:button]; 


     [self.viewScrollCategories addSubview:effectView]; 

     button = nil; 

    }); 

    if(current_items_per_row < 3){ 
     current_items_per_row++; 
     item_x_axis = item_x_axis + item_width; 
    }else { 
     current_row_height = current_row_height + item_height; 
     current_items_per_row = 1; 
     item_x_axis = 0; 
    } 

} 

Любая идея, как решить эту проблему? он, похоже, отлично работал на IPhone.

EDIT

Это код, который звонит фоновый поток (shortned)

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo: (NSDictionary *)info { 


//[self generatingThumbnailMessageShow]; 

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    [self loadAllEffects]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     [self generatingThumbnailMessageHide]; 
    }); 
}); 

} 
+0

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

+0

Да, редактирование изображений занимает много времени. Поток генерирует отредактированные изображения с использованием разных эффектов, и есть 20+ эффектов, поэтому требуется несколько секунд или два, чтобы редактировать все изображения и создавать эскизы. – ORStudios

+0

Ну, глядя на ваш код, мне кажется, что то, что вы делаете в основном потоке, должно быть очень быстрым: вы просто создаете некоторые подзапросы и вставляете их в интерфейс. Таким образом, задержка, которую вы испытываете, может исходить от редактирования изображения. – matt

ответ

2

Ну, вы просят за задержку с dispatch_async(dispatch_get_main_queue().... Этот код означает «Пожалуйста, делайте это каждый раз, когда у вас есть время, когда мой текущий код закончится». Как только вы это скажете, вы в основном говорите, что вам все равно, когда этот код работает. Вы надеетесь, что наступит некоторое время довольно скоро, но вы оставили время выполнения, чтобы позаботиться о деталях.

Возможно, именно эта «надежда» является проблемой. Архитектура процессоров устройств отличается, и модель потоков для устройства может изменить способ реагирования устройства на то, что куча этих отложенных запросов накапливается.

Я не совсем понимаю, что вы пытаетесь выполнить в этом коде (извините, tl:dr), но использование отложенной производительности в середине и ваша жалоба на то, что существует «5-15 секунд delay "похоже, что-то вместе ...

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

ДРУГОЙ РЕДАКТОР: Просто дикая и сумасшедшая идея здесь. Если требуется время обработки изображений, почему бы вам не сделать все обработку изображений, а затем выполнить обновление интерфейса по основной теме раз? Я имею в виду, что вы делаете это:

for (id effect in effectArray) { 
    UIImage *tmp = // ... 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     // ... 
     [imagepreview setImage:tmp]; 

Таким образом, вы каждый раз возвращаетесь к основному потоку каждый раз через цикл. Почему бы не попробовать это:

dispatch_async(dispatch_get_main_queue(), ^{ 
    for (id effect in effectArray) { 
     UIImage *tmp = // ... 
     // ... 
     [imagepreview setImage:tmp]; 

Теперь вы просто получить обратно в главном потоке раз. При обработке изображений будет задержка, но тогда интерфейс должен просто обновиться, badda bing badda boom (технический термин программирования).

+0

Привет, см. Вышеупомянутый вопрос, я отредактировал его, чтобы показать код, вызывающий фоновый поток. Я в основном загружаю изображение и показываю сообщение «Создание эскиза». Фоновый поток запускает код эскиза, а затем, когда он завершен, сообщение удаляется. – ORStudios

+0

Хорошая идея, и она, похоже, сработала. Я закончил создание пустого массива, а затем прокрутил изображения и добавил их в массив. Затем я поместил второй цикл для обработки эскизов внутри вызова main_thread, а затем зациклился и сопоставил текущий индекс с индексом в массиве изображений. Спасибо за помощь! – ORStudios

+0

Ничего себе, неплохо, учитывая, что я был довольно летающим слепым на этом! :) Да, резьба * жесткая *. В дополнение к вопросам скорости вы должны быть очень осторожны. – matt

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