iOS异步加载网络图片

在iOS中加载网络图片有多种方式:

法1:在主线程中同步加载网络图片

在主线程中加载图片,先将图片的URL存放进NSURL,然后再用这个NSURL初始化NSData,再把UIImage用NSData初始化,就行了。代码如下:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    if ([tableView isEqual:self.tableView]) {
        cell.textLabel.text = @"Synchronized Loading";
        
        // synchronized image loading
        NSURL *imageURL = [NSURL URLWithString:@"http://www.i-programmer.info/images/stories/News/2011/MARCH/CMULOGO.jpg"];
        NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
        cell.imageView.image = [UIImage imageWithData:imageData];
    }
    return cell;
}

但是这种方法会阻塞主线程,也就是只有等图片这段代码执行后,页面才能够被进入。

法2:使用NSOperationQueue异步加载

一个NSOperationQueue 操作队列,就相当于一个线程管理器,而非一个线程。因为你可以设置这个线程管理器内可以并行运行的的线程数量。代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.title = @"NSOperationQueue异步加载";
    [self.view addSubview:self.tableView];
    
    NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage) object:nil];
    [operationQueue addOperation:op];
}

- (void)downloadImage {
    NSURL *imageURL = [NSURL URLWithString:@"http://www.iconpng.com/png/socialnetworks2/linkedin.png"];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:imageData];
    [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
}

- (void)updateUI:(UIImage*)image {
    self.image = image;
    [self.tableView reloadData];
}

法3:Cache缓存+同步加载

第一次加载的时候用同步加载,同时把图片缓存到沙箱目录中,第二次及以后的加载就直接从本地目录中加载。

1)首先建立一个缓存目录

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString * diskCachePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"imageCache"];
    
    //如果目录imageCache不存在,创建目录
    if (![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath]) {
        NSLog(@"fuck1");
        NSError *error = nil;
        [[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath withIntermediateDirectories:YES attributes:nil error:&error];
    }

2)如果本地缓存没有,则保存图片到对应的路径。若本地缓存有图片,则直接从缓存中加载图片

<pre name="code" class="objc">    for (int i = 0; i < self.urlArray.count; i++) {
        NSURL *imageURL = self.urlArray[i];
        
        // 如果本地缓存没有,保存图片
        NSString *localPath = [NSString stringWithFormat:@"%@/headimage%d.png", diskCachePath, i];
        if (![[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
            NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
            [imageData writeToFile:localPath atomically:YES];
        }
        
        // 如果存在本地缓存图片,直接读取cache内的缓存图片
        if ([[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
            NSData *data = [NSData dataWithContentsOfFile:localPath];
            UIImage *image = [UIImage imageWithData:data];
            [self.imageArray addObject:image];
        }
    }

我写的Demo的下载地址如右:http://download.csdn.net/detail/luoshengkim/9481601

关于iOS多线程编程,可以参考这个链接:http://blog.csdn.net/totogo2010/article/details/8013316

    原文作者:月光下的夜曲
    原文地址: https://blog.csdn.net/luoshengkim/article/details/51037912
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞