自定义NSOperation 下载图片

/** 

 学习点:1. 自定义NSOperation

 2. 代理传值

 3. 只下载一次网络资源 

 4. 刷新UI

 5. 多线程技术

  */

步骤:

1. 创建继承自NSOperation

2. 代理传值

3. 刷新cell

4. 以下主要代码


 //
//  HMViewController.h
//  04-自定义Operation
//
//  Created by apple on 14-6-24.
//  Copyright (c) 2014年 heima. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface HMViewController : UITableViewController

@end


//
//  HMViewController.m
//  04-自定义Operation
//
//  Created by apple on 14-6-24.
//  Copyright (c) 2014年 heima. All rights reserved.
//


#import "HMApp.h"
#import "HMViewController.h"
#import "HMDownloadOperation.h"


@interface HMViewController () <HMDownloadOperationDelegate>
@property (nonatomic, strong) NSArray *apps;
@property (nonatomic, strong) NSOperationQueue *queue;
/** key:url value:operation对象 */
@property (nonatomic, strong) NSMutableDictionary *operations;


/** key:url value:image对象*/
@property (nonatomic, strong) NSMutableDictionary *images;
@end


@implementation HMViewController


- (NSArray *)apps
{
    if (!_apps) {
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil]];
        
        NSMutableArray *appArray = [NSMutableArray array];
        for (NSDictionary *dict in dictArray) {
            HMApp *app = [HMApp appWithDict:dict];
            [appArray addObject:app];
        }
        _apps = appArray;
    }
    return _apps;
}


- (NSOperationQueue *)queue
{
    if (!_queue) {
        _queue = [[NSOperationQueue alloc] init];
        _queue.maxConcurrentOperationCount = 3; // 最大并发数 == 3
    }
    return _queue;
}


- (NSMutableDictionary *)operations
{
    if (!_operations) {
        _operations = [NSMutableDictionary dictionary];
    }
    return _operations;
}


- (NSMutableDictionary *)images
{
    if (!_images) {
        _images = [NSMutableDictionary dictionary];
    }
    return _images;
}


- (void)viewDidLoad
{
    [super viewDidLoad];
    
}


#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.apps.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"app";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
    
    HMApp *app = self.apps[indexPath.row];
    cell.textLabel.text = app.name;
    cell.detailTextLabel.text = app.download;
    
    // 显示图片
    // 保证一个url对应一个HMDownloadOperation
    // 保证一个url对应UIImage对象
    
    UIImage *image = self.images[app.icon];
    if (image) { // 缓存中有图片
        cell.imageView.image = image;
    } else { // 缓存中没有图片, 得下载
        cell.imageView.image = [UIImage imageNamed:@"57437179_42489b0"];
        
        HMDownloadOperation *operation = self.operations[app.icon];
        if (operation) { // 正在下载
            // ... 暂时不需要做其他事
            
        } else { // 没有正在下载
            // 创建操作
            operation = [[HMDownloadOperation alloc] init];
            operation.url = app.icon;
            operation.delegate = self;
            operation.indexPath = indexPath;
            [self.queue addOperation:operation]; // 异步下载
            
            self.operations[app.icon] = operation;
        }
    }
    
    // SDWebImage : 专门用来下载图片
    return cell;
}


#pragma mark - HMDownloadOperationDelegate
- (void)downloadOperation:(HMDownloadOperation *)operation didFinishDownload:(UIImage *)image
{
    // 1.移除执行完毕的操作
    [self.operations removeObjectForKey:operation.url];
    
    if (image) {
        // 2.将图片放到缓存中(images)
        self.images[operation.url] = image;
        
        // 3.刷新表格
        [self.tableView reloadRowsAtIndexPaths:@[operation.indexPath] withRowAnimation:UITableViewRowAnimationNone];
        
        // 3.将图片写入沙盒
//        NSData *data = UIImagePNGRepresentation(image);
//        [data writeToFile:@"" atomically:<#(BOOL)#>];
    }
    
}


- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    // 开始拖拽
    // 暂停队列
    [self.queue setSuspended:YES];
}


- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
    [self.queue setSuspended:NO];
}

@end


//
//  HMDownloadOperation.h
//  04-自定义Operation
//
//  Created by apple on 14-6-24.
//  Copyright (c) 2014年 heima. All rights reserved.
//  一个下载操作就交给一个HMDownloadOperation对象


#import <Foundation/Foundation.h>


@class HMDownloadOperation;


@protocol HMDownloadOperationDelegate <NSObject>
@optional
- (void)downloadOperation:(HMDownloadOperation *)operation didFinishDownload:(UIImage *)image;
@end


@interface HMDownloadOperation : NSOperation
@property (nonatomic, copy) NSString *url;
@property (nonatomic, strong) NSIndexPath *indexPath;
@property (nonatomic, weak) id<HMDownloadOperationDelegate> delegate;
@end


//
//  HMDownloadOperation.m
//  04-自定义Operation
//
//  Created by apple on 14-6-24.
//  Copyright (c) 2014年 heima. All rights reserved.
//


#import "HMDownloadOperation.h"


@implementation HMDownloadOperation


/**
 *  在main方法中实现具体操作
 */
- (void)main
{
    @autoreleasepool {
        
        NSURL *downloadUrl = [NSURL URLWithString:self.url];
        NSData *data = [NSData dataWithContentsOfURL:downloadUrl]; // 这行会比较耗时
        UIImage *image = [UIImage imageWithData:data];


        if ([self.delegate respondsToSelector:@selector(downloadOperation:didFinishDownload:)]) {
            dispatch_async(dispatch_get_main_queue(), ^{ // 回到主线程, 传递图片数据给代理对象
                [self.delegate downloadOperation:self didFinishDownload:image];
            });
        }
    }
}
@end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值