Ios 我可以异步UIImageJPEG表示文件吗?

Ios 我可以异步UIImageJPEG表示文件吗?,ios,objective-c,multithreading,Ios,Objective C,Multithreading,当我从服务器返回映像时,我正在执行以下操作。但这段代码让我的应用程序崩溃了。它冻结了用户界面 这可以在iOS的后台线程上运行吗?我可以使用异步吗 if (![NSString isEmpty:user.avatarURL]) { NSString *pathToImage = user.avatarURL; NSURL *url = [NSURL URLWithString:pathToImage]; NSData *data = [NSData dataWit

当我从服务器返回映像时,我正在执行以下操作。但这段代码让我的应用程序崩溃了。它冻结了用户界面

这可以在iOS的后台线程上运行吗?我可以使用异步吗

 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];                                           
 }

造成最大损坏的线路是:

 NSData *data = [NSData dataWithContentsOfURL:url];

因为它是从网络上下载的。代码中的任何内容都不会更新UI,因此它可以在后台线程上运行。只要确保在保存图像后发布通知或随后更新UI时切换回主线程即可。

造成最大损坏的行是:

 NSData *data = [NSData dataWithContentsOfURL:url];

因为它是从网络上下载的。代码中的任何内容都不会更新UI,因此它可以在后台线程上运行。只要确保在保存图像后发布通知或随后更新UI时切换回主线程即可。

正如@valentin所说,您可以在dispatch\u async()调用中执行if()语句中的所有操作

注意:我怀疑可能是
-dataWithContentsOfURL:
,而不是
UIImageJPEGRepresentation()
,使您的速度变慢了,因此您需要确保它在您的dispatch\u 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];                                           
    });

正如@valentin所说,您可以在dispatch\u async()调用中的if()语句中执行所有操作

注意:我怀疑可能是
-dataWithContentsOfURL:
,而不是
UIImageJPEGRepresentation()
,使您的速度变慢了,因此您需要确保它在您的dispatch\u 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];                                           
    });

我不明白为什么不使用
dispatch\u async
。是的,您可以从代码中使用async。看起来您没有在UI部分执行任何操作,因此您可以轻松地在后台执行此代码。您可以使用调度队列。我不明白为什么不使用
dispatch\u async
。是的,您可以从代码中使用Async。看起来您并没有在UI部分执行任何操作,所以您可以轻松地在后台执行此代码。您可以使用dispatch_队列来执行此操作。