/**
学习点: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