2014-02-10 4 views
1

Я делаю следующее, когда возвращаю изображение с сервера. Но этот код приносит мое приложение на колени. Он зависает от пользовательского интерфейса.Могу ли я асинхронно UIImageJPEGПреобразование writeToFile?

Может ли это работать на фоне потока в iOS? Могу ли я использовать async?

if (![NSString isEmpty:user.avatarURL]) 
{ 
    NSString *pathToImage = user.avatarURL; 
    NSURL *url = [NSURL URLWithString:pathToImage]; 
    NSData *data = [NSData dataWithContentsOfURL:url]; 
    UIImage *image = [[UIImage alloc] initWithData:data]; 

    [[NSUserDefaults standardUserDefaults] setObject:UIImageJPEGRepresentation(image, 1) forKey:kUserImage]; 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,                        NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString* path = [documentsDirectory stringByAppendingPathComponent:@"userAvatar.png" ]; 
    NSData* jpegdata = UIImageJPEGRepresentation(image, 1); 
    [jpegdata writeToFile:path atomically:YES];           
} 
+1

Я не вижу, почему бы не использовать 'dispatch_async'. ДА, вы можете использовать async –

+1

Из вашего кода кажется, что вы ничего не делаете в части пользовательского интерфейса, поэтому вы можете легко выполнить этот код в фоновом режиме. Для этого вы можете использовать dispatch_queues. – IOSCODER

ответ

3

Как говорит @valentin, вы можете делать все внутри оператора if() в вызове dispatch_async().

Примечание. Я подозреваю, что на самом деле это замедление на самом деле является -dataWithContentsOfURL:, а не UIImageJPEGRepresentation(), поэтому вы должны убедиться, что это находится внутри вашего dispatch_async, а не снаружи.

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

Я хотел бы сделать следующее:

if (user.avatarURL) 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     NSURL *const imageURL = [NSURL URLWithString:user.avatarURL]; 
     if (!imageURL) 
      return; 
     NSData *const imageDdata = [NSData dataWithContentsOfURL:imageURL]; 
     if (!imageDdata.length) 
      return; 

     [[NSUserDefaults standardUserDefaults] setObject:imageDdata forKey:kUserImage]; 

     [imageDdata writeToFile:[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"userAvatar.png"] atomically:YES];           
    }); 
1

линия, которая делает наибольший ущерб является:

NSData *data = [NSData dataWithContentsOfURL:url]; 

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

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