- NSOperation
// 继承NSOperation
@interface MyNSoperation : NSOperation
@property (nonatomic, strong) UIImage *image;
@end
@implementation MyNSoperation
- (void)main {
_image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://ws3.sinaimg.cn/large/006tKfTcgy1fjt9s573oxj30zk0qo0vp.jpg"]]];
}
@end
// 使用NSOperation
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
_myImageView.image = nil;
MyNSoperation *op = [[MyNSoperation alloc] init];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
__weak typeof(op) waekOp = op;
op.completionBlock = ^{
UIImage *image = waekOp.image;
dispatch_async(dispatch_get_main_queue(), ^{
_myImageView.image = image;
});
};
[queue addOperation:op];
}
-
现成的继承类
- NSBlockOperation
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { _myImageView.image = nil; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{ UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://ws3.sinaimg.cn/large/006tKfTcgy1fjt9s573oxj30zk0qo0vp.jpg"]]]; dispatch_async(dispatch_get_main_queue(), ^{ self.myImageView.image = image; }); }]; [queue addOperation:op]; }
- NSInvocationOperation
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { _myImageView.image = nil; NSOperationQueue *queue = [[NSOperationQueue alloc] init]; NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage) object:nil]; [queue addOperation:op]; } - (void)downloadImage { UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"https://ws3.sinaimg.cn/large/006tKfTcgy1fjt9s573oxj30zk0qo0vp.jpg"]]]; dispatch_async(dispatch_get_main_queue(), ^{ _myImageView.image = image; }); }
- 控制Queue最大并发数(为1时是串行Queue)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 3;
- 获取主线程
[NSOperationQueue mainQueue];
- 读取当前Operation个数
[queue operationCount];
-
cancel
cancel在队列中的Operation不会执行其中的main函数,直接调用complete。
cancel在线程中的Operation,该Operation被标记为isCancel,继续执行完其中的main函数,执行complete。
cancel还未加入队列中的Operation则直接变成cancel状态
- 等待队列完成后继续操作
[queue waitUntilAllOperationsAreFinished];
等待Operation完成
等待依赖的Operation完成 - Dependency
#import "FirstViewController.h"
@interface FirstViewController () {
NSArray *_urls;
NSOperationQueue *_downloadImageQueue;
NSBlockOperation *_finalOperation;
}
@property (weak, nonatomic) IBOutlet UIImageView *imageView1;
@property (weak, nonatomic) IBOutlet UIImageView *imageView2;
@property (weak, nonatomic) IBOutlet UIImageView *imageView3;
@property (weak, nonatomic) IBOutlet UIImageView *indicateImageView;
@end
@implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
_urls = @[@"https://ws3.sinaimg.cn/large/006tKfTcgy1fjt9s573oxj30zk0qo0vp.jpg",
@"https://ws3.sinaimg.cn/large/006tKfTcgy1fjtg0xmaptj30lz082q41.jpg",
@"https://ws2.sinaimg.cn/large/006tKfTcgy1fjtise0maxj30ia0pljsm.jpg"];
_downloadImageQueue = [[NSOperationQueue alloc] init];
[self finishedDownload];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSArray *imageViews =@[_imageView1, _imageView2, _imageView3];
[_downloadImageQueue setMaxConcurrentOperationCount:3];
for (NSString *urlString in _urls) {
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]]];
dispatch_async(dispatch_get_main_queue(), ^{
((UIImageView *)[imageViews objectAtIndex:[_urls indexOfObject:urlString]]).image = image;
});
}];
[_downloadImageQueue addOperation:op];
[_finalOperation addDependency:op];
}
NSOperationQueue *finalQueue = [[NSOperationQueue alloc] init];
[finalQueue addOperation:_finalOperation];
}
- (void)finishedDownload {
_finalOperation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"finished!");
dispatch_async(dispatch_get_main_queue(), ^{
[_indicateImageView setHidden:YES];
});
}];
}
@end
-
循环依赖
- 优先级
// 高优先级总在低优先级之前运行
typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
NSOperationQueuePriorityVeryLow = -8L,
NSOperationQueuePriorityLow = -4L,
NSOperationQueuePriorityNormal = 0,
NSOperationQueuePriorityHigh = 4,
NSOperationQueuePriorityVeryHigh = 8
};
@property NSOperationQueuePriority queuePriority;
高优先级的Operation进入队列会挤占低优先级Operation的位置,但是不会挤占正在运行的Operation的位置