#import <Foundation/Foundation.h>
/**
完成回调
*/
#warning mark - block在主线程中创建 回调就必须用主线程
typedef void(^OperationDidFinishBlock)(void);
/**
进度回调
*/
typedef void(^OPerationDidRecieveProgressBlock)(float progress);
@interface MyOperation : NSOperation
/**
* NSURL构造方法
*/
- (id)initWithUrl:(NSURL *)url;
/**
* 完成回调
*
* @param finishblock <#finishblock description#>
*/
- (void)setOPerationDidFinish:(OperationDidFinishBlock)finishBlock;
/**
* 进度回调
*/
- (void)setOperationDIdFinishRecieveProgressBlock:(OPerationDidRecieveProgressBlock)progress;
@end
#import "MyOperation.h"
@interface MyOperation ()<NSURLConnectionDataDelegate>
{
NSURL *_url;
//是否停止下载
BOOL _isEndRequest;
//完成回调
OperationDidFinishBlock _finishBlock;
//进度回调
OPerationDidRecieveProgressBlock _progressBlock;
//文件总大小
long long _filesize;
}
@property(nonatomic, strong)NSMutableData *downloadData;
@end
@implementation MyOperation
- (id)initWithUrl:(NSURL *)url
{
if (self = [super init]) {
_url = url;
}
return self;
}
//子线程
- (void)main
{
NSLog(@"main 方法自动调用%d",[NSThread isMainThread]);
[self startRequest];//发送异步请求
while (!_isEndRequest) {
//主线程runloop 默认是启动的 分线程要手动启动
[[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
NSLog(@"main方法完成 任务取消");
}
//发送请求
- (void)startRequest
{
[NSURLConnection connectionWithRequest:[NSURLRequest requestWithURL:_url] delegate:self];
}
#pragma mark - getter方法
- (NSMutableData *)downloadData
{
if (!_downloadData) {
_downloadData = [NSMutableData data];
}
return _downloadData;
}
#pragma mark - setter方法
- (void)setOPerationDidFinish:(OperationDidFinishBlock)finishBlock
{
_finishBlock = finishBlock;
}
- (void)setOperationDIdFinishRecieveProgressBlock:(OPerationDidRecieveProgressBlock)progress
{
_progressBlock = progress;
}
#pragma mark - NSURLConnectionDataDelegate代理方法
/**
* 响应头
*
* @param connection <#connection description#>
* @param response <#response description#>
*/
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSLog(@"收到服务器响应");
self.downloadData.length = 0;
//文件大小
_filesize = [response expectedContentLength];
}
/**
* 接受数据
*
* @param connection <#connection description#>
* @param data <#data description#>
*/
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
//接受数据
[self.downloadData appendData:data];
//计算进度
float progress = (float)self.downloadData.length/_filesize;
//进度回调
dispatch_async(dispatch_get_main_queue(), ^{
if (_progressBlock) {
_progressBlock(progress);
}
});
}
/**
* 连接完成
*
* @param connection <#connection description#>
*/
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"请求完成");
dispatch_async(dispatch_get_main_queue(), ^{
if (_finishBlock) {
_finishBlock();
}
});
_isEndRequest = YES;
}
/**
* 连接失败
*
* @param connection <#connection description#>
* @param error <#error description#>
*/
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"出错信息:-- %@",error);
_isEndRequest = YES;
}
@end
#import "NSOperationViewController.h"
#import "MyOperation.h"
@interface NSOperationViewController ()
{
NSArray *_urls;
}
@property (nonatomic, strong)NSOperationQueue *queue;
@end
@implementation NSOperationViewController
#pragma mark - getter方法
- (NSOperationQueue *)queue
{
if (!_queue) {
_queue = [[NSOperationQueue alloc]init];
_queue.maxConcurrentOperationCount = 3;
}
return _queue;
}
- (void)viewDidLoad {
[super viewDidLoad];
_urls = @[@"http://dl_dir.qq.com/qqfile/qq/QQforMac/QQ_V2.4.1.dmg",
@"http://dl_dir.qq.com/qqfile/qq/QQforMac/QQ_V2.4.1.dmg",
@"http://assets.sbnation.com/assets/2512203/dogflops.gif"];
for (int i = 0; i < _urls.count; i++) {
UIProgressView *progressView = (UIProgressView *)[self.view viewWithTag:i + 1];
MyOperation *operation = [[MyOperation alloc]initWithUrl:[NSURL URLWithString:_urls[i]]];
//设置进度回调
[operation setOperationDIdFinishRecieveProgressBlock:^(float progress) {
progressView.progress = progress;
}];
//设置下载完成回调
[operation setOPerationDidFinish:^{
NSString *message = [NSString stringWithFormat:@"第%d个任务完成",i+1];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}];
[self.queue addOperation:operation];
}
// BOOL a;
// NSLog(@"%d",a);
#if 0
添加依赖关系需要注意:
1.添加依赖关系到 addOperation
2.不要添加循环依赖
#endif
//取消任务
//[operation cancel];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)awakeFromNib
{
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end