NSInvocationOperation
1、在主線程中使用
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSURL *url = [NSURL URLWithString:@"abc"] ;
NSInvocationOperation *inv = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImgFromURL:) object:url];
[inv start];
}
- (void)downloadImgFromURL:(NSURL *)url {
NSLog(@"%@___%@",url,[NSThread currentThread]);
}
2018-10-10 14:29:42.285163+0800 Visit_Thread[4244:242395] abc___<NSThread: 0x60000006ea80>{number = 1, name = main}
2亥宿、多線程
當(dāng)maxConcurrentOperationCount
小于當(dāng)前任務(wù)數(shù)時(shí)會(huì)出現(xiàn)這樣的情況(很容易理解3個(gè)任務(wù),2條線程):
2條線程跑滿2個(gè)任務(wù),當(dāng)一個(gè)線程中的任務(wù)執(zhí)行完畢,再?gòu)年?duì)列中去取新的任務(wù)
如果設(shè)置最大并發(fā)數(shù)為1邮旷,那么任務(wù)將會(huì)串行執(zhí)行(在不同的線程執(zhí)行,但是執(zhí)行順序是串行的)
注意:串行執(zhí)行任務(wù) 不等于 只開一條線程
如果設(shè)置最大并發(fā)數(shù)為0蝇摸,那么任務(wù)將不會(huì)執(zhí)行如果設(shè)置最大并發(fā)數(shù)為-1廊移,表示最大并發(fā)數(shù)不受限制
- (void)test7 {
NSLog(@"start");
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
queue.maxConcurrentOperationCount = 2;
NSURL *url = [NSURL URLWithString:@"abc"] ;
NSInvocationOperation *task1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImgFromURL1:) object:url];
[queue addOperation:task1];
NSInvocationOperation *task2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImgFromURL2:) object:url];
[queue addOperation:task2];
NSInvocationOperation *task3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImgFromURL3:) object:url];
[queue addOperation:task3];
NSLog(@"end");
}
- (void)downloadImgFromURL1:(NSURL *)url {
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"1___%@",[NSThread currentThread]);
}
}
- (void)downloadImgFromURL2:(NSURL *)url {
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2___%@",[NSThread currentThread]);
}
}
- (void)downloadImgFromURL3:(NSURL *)url {
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3___%@",[NSThread currentThread]);
}
}
2018-10-10 14:58:31.460019+0800 Visit_Thread[4774:280702] start
2018-10-10 14:58:31.460932+0800 Visit_Thread[4774:280702] end
2018-10-10 14:58:33.463473+0800 Visit_Thread[4774:280744] 2___<NSThread: 0x60400007b840>{number = 3, name = (null)}
2018-10-10 14:58:33.463479+0800 Visit_Thread[4774:280746] 1___<NSThread: 0x60000066a980>{number = 4, name = (null)}
2018-10-10 14:58:35.468851+0800 Visit_Thread[4774:280744] 2___<NSThread: 0x60400007b840>{number = 3, name = (null)}
2018-10-10 14:58:35.468870+0800 Visit_Thread[4774:280746] 1___<NSThread: 0x60000066a980>{number = 4, name = (null)}
2018-10-10 14:58:37.474366+0800 Visit_Thread[4774:280746] 1___<NSThread: 0x60000066a980>{number = 4, name = (null)}
2018-10-10 14:58:37.474367+0800 Visit_Thread[4774:280744] 2___<NSThread: 0x60400007b840>{number = 3, name = (null)}
2018-10-10 14:58:39.479901+0800 Visit_Thread[4774:280744] 2___<NSThread: 0x60400007b840>{number = 3, name = (null)}
2018-10-10 14:58:39.479903+0800 Visit_Thread[4774:280745] 3___<NSThread: 0x60400026a700>{number = 5, name = (null)}
2018-10-10 14:58:41.485467+0800 Visit_Thread[4774:280745] 3___<NSThread: 0x60400026a700>{number = 5, name = (null)}
2018-10-10 14:58:41.485467+0800 Visit_Thread[4774:280744] 2___<NSThread: 0x60400007b840>{number = 3, name = (null)}
2018-10-10 14:58:43.491001+0800 Visit_Thread[4774:280745] 3___<NSThread: 0x60400026a700>{number = 5, name = (null)}
2018-10-10 14:58:45.496507+0800 Visit_Thread[4774:280745] 3___<NSThread: 0x60400026a700>{number = 5, name = (null)}
2018-10-10 14:58:47.502031+0800 Visit_Thread[4774:280745] 3___<NSThread: 0x60400026a700>{number = 5, name = (null)}
如果最大線程數(shù)超過當(dāng)前任務(wù)數(shù),那么也只會(huì)開和當(dāng)前任務(wù)數(shù)相同的線程探入,多個(gè)任務(wù)狡孔,并發(fā)執(zhí)行:
queue.maxConcurrentOperationCount = 5;
2018-10-10 15:02:01.148009+0800 Visit_Thread[4837:285412] start
2018-10-10 15:02:01.148893+0800 Visit_Thread[4837:285412] end
2018-10-10 15:02:03.152383+0800 Visit_Thread[4837:285465] 2___<NSThread: 0x60000047cf40>{number = 5, name = (null)}
2018-10-10 15:02:03.152388+0800 Visit_Thread[4837:285467] 1___<NSThread: 0x60000047cdc0>{number = 3, name = (null)}
2018-10-10 15:02:03.152383+0800 Visit_Thread[4837:285468] 3___<NSThread: 0x60400026d1c0>{number = 4, name = (null)}
2018-10-10 15:02:05.155475+0800 Visit_Thread[4837:285467] 1___<NSThread: 0x60000047cdc0>{number = 3, name = (null)}
2018-10-10 15:02:05.155489+0800 Visit_Thread[4837:285468] 3___<NSThread: 0x60400026d1c0>{number = 4, name = (null)}
2018-10-10 15:02:05.155481+0800 Visit_Thread[4837:285465] 2___<NSThread: 0x60000047cf40>{number = 5, name = (null)}
2018-10-10 15:02:07.159810+0800 Visit_Thread[4837:285465] 2___<NSThread: 0x60000047cf40>{number = 5, name = (null)}
2018-10-10 15:02:07.159821+0800 Visit_Thread[4837:285467] 1___<NSThread: 0x60000047cdc0>{number = 3, name = (null)}
2018-10-10 15:02:07.159815+0800 Visit_Thread[4837:285468] 3___<NSThread: 0x60400026d1c0>{number = 4, name = (null)}
2018-10-10 15:02:09.163067+0800 Visit_Thread[4837:285465] 2___<NSThread: 0x60000047cf40>{number = 5, name = (null)}
2018-10-10 15:02:09.163066+0800 Visit_Thread[4837:285468] 3___<NSThread: 0x60400026d1c0>{number = 4, name = (null)}
2018-10-10 15:02:11.168004+0800 Visit_Thread[4837:285468] 3___<NSThread: 0x60400026d1c0>{number = 4, name = (null)}
2018-10-10 15:02:11.168000+0800 Visit_Thread[4837:285465] 2___<NSThread: 0x60000047cf40>{number = 5, name = (null)}
NSBlockOperation
1、在主線程中使用
如果任務(wù)開始之后再追加任務(wù)蜂嗽,程序會(huì)cache:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSBlockOperation addExecutionBlock:]: blocks cannot be added after the operation has started executing or finished
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"start");
NSBlockOperation *task1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"1___%@",[NSThread currentThread]);
}];
NSBlockOperation *task2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"2___%@",[NSThread currentThread]);
}];
NSBlockOperation *task3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"3___%@",[NSThread currentThread]);
}];
//追加任務(wù)
[task1 addExecutionBlock:^{
NSLog(@"1+++%@",[NSThread currentThread]);
}];
[task2 addExecutionBlock:^{
NSLog(@"2+++%@",[NSThread currentThread]);
}];
[task3 addExecutionBlock:^{
NSLog(@"3+++%@",[NSThread currentThread]);
}];
[task3 start];//先開始苗膝,先執(zhí)行
[task1 start];
[task2 start];
NSLog(@"end");
}
2018-10-10 14:41:09.361581+0800 Visit_Thread[4436:258615] start
2018-10-10 14:41:09.361974+0800 Visit_Thread[4436:258615] 3___<NSThread: 0x60000007cf00>{number = 1, name = main}
2018-10-10 14:41:09.361975+0800 Visit_Thread[4436:259265] 3+++<NSThread: 0x6000006667c0>{number = 8, name = (null)}
2018-10-10 14:41:09.362169+0800 Visit_Thread[4436:258615] 1___<NSThread: 0x60000007cf00>{number = 1, name = main}
2018-10-10 14:41:09.362182+0800 Visit_Thread[4436:259265] 1+++<NSThread: 0x6000006667c0>{number = 8, name = (null)}
2018-10-10 14:41:09.362635+0800 Visit_Thread[4436:259265] 2+++<NSThread: 0x6000006667c0>{number = 8, name = (null)}
2018-10-10 14:41:09.362643+0800 Visit_Thread[4436:258615] 2___<NSThread: 0x60000007cf00>{number = 1, name = main}
2018-10-10 14:41:09.362886+0800 Visit_Thread[4436:258615] end
2018-10-10 14:40:22.773672+0800 Visit_Thread[4436:258615] start
2018-10-10 14:40:22.774083+0800 Visit_Thread[4436:258615] 3___<NSThread: 0x60000007cf00>{number = 1, name = main}
2018-10-10 14:40:22.774114+0800 Visit_Thread[4436:258911] 3+++<NSThread: 0x60400046fc80>{number = 5, name = (null)}
2018-10-10 14:40:22.774752+0800 Visit_Thread[4436:258911] 1+++<NSThread: 0x60400046fc80>{number = 5, name = (null)}
2018-10-10 14:40:22.774753+0800 Visit_Thread[4436:258615] 1___<NSThread: 0x60000007cf00>{number = 1, name = main}
2018-10-10 14:40:22.774943+0800 Visit_Thread[4436:258615] 2___<NSThread: 0x60000007cf00>{number = 1, name = main}
2018-10-10 14:40:22.774951+0800 Visit_Thread[4436:258911] 2+++<NSThread: 0x60400046fc80>{number = 5, name = (null)}
2018-10-10 14:40:22.775110+0800 Visit_Thread[4436:258615] end
通過打印結(jié)果可知:先開始,先執(zhí)行植旧;
但是開始的任務(wù)中辱揭,是先執(zhí)行原任務(wù)還是先執(zhí)行追加任務(wù)离唐,這個(gè)是不確定的;
原任務(wù)是在主線程中執(zhí)行的问窃,但是追加的任務(wù)都是在子線程中執(zhí)行的亥鬓;
多線程
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"start");
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
// queue.maxConcurrentOperationCount = 5;
NSBlockOperation *task1 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"1___%@",[NSThread currentThread]);
}
}];
NSBlockOperation *task2 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2___%@",[NSThread currentThread]);
}
}];
NSBlockOperation *task3 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3___%@",[NSThread currentThread]);
}
}];
//追加任務(wù)
[task1 addExecutionBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:1];
NSLog(@"1+++%@",[NSThread currentThread]);
}
}];
[task2 addExecutionBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2+++%@",[NSThread currentThread]);
}
}];
[task3 addExecutionBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:3];
NSLog(@"3+++%@",[NSThread currentThread]);
}
}];
[queue addOperation:task1];
[queue addOperation:task2];
[queue addOperation:task3];
NSLog(@"end");
}
2018-10-10 15:13:38.464338+0800 Visit_Thread[5027:297309] start
2018-10-10 15:13:38.464920+0800 Visit_Thread[5027:297309] end
2018-10-10 15:13:39.465737+0800 Visit_Thread[5027:297386] 1+++<NSThread: 0x60400027e980>{number = 3, name = (null)}
2018-10-10 15:13:40.469689+0800 Visit_Thread[5027:297364] 2___<NSThread: 0x604000465c40>{number = 5, name = (null)}
2018-10-10 15:13:40.469701+0800 Visit_Thread[5027:297365] 1___<NSThread: 0x604000465b80>{number = 4, name = (null)}
2018-10-10 15:13:40.469708+0800 Visit_Thread[5027:297386] 1+++<NSThread: 0x60400027e980>{number = 3, name = (null)}
2018-10-10 15:13:40.469735+0800 Visit_Thread[5027:297367] 3___<NSThread: 0x600000670640>{number = 6, name = (null)}
2018-10-10 15:13:40.469735+0800 Visit_Thread[5027:297385] 2+++<NSThread: 0x600000670880>{number = 7, name = (null)}
2018-10-10 15:13:41.468790+0800 Visit_Thread[5027:297366] 3+++<NSThread: 0x604000465dc0>{number = 8, name = (null)}
2018-10-10 15:13:41.475239+0800 Visit_Thread[5027:297386] 1+++<NSThread: 0x60400027e980>{number = 3, name = (null)}
2018-10-10 15:13:42.475216+0800 Visit_Thread[5027:297367] 3___<NSThread: 0x600000670640>{number = 6, name = (null)}
2018-10-10 15:13:42.475216+0800 Visit_Thread[5027:297365] 1___<NSThread: 0x604000465b80>{number = 4, name = (null)}
2018-10-10 15:13:42.475227+0800 Visit_Thread[5027:297364] 2___<NSThread: 0x604000465c40>{number = 5, name = (null)}
2018-10-10 15:13:42.475260+0800 Visit_Thread[5027:297385] 2+++<NSThread: 0x600000670880>{number = 7, name = (null)}
2018-10-10 15:13:44.469294+0800 Visit_Thread[5027:297366] 3+++<NSThread: 0x604000465dc0>{number = 8, name = (null)}
2018-10-10 15:13:44.479592+0800 Visit_Thread[5027:297364] 2___<NSThread: 0x604000465c40>{number = 5, name = (null)}
2018-10-10 15:13:44.479596+0800 Visit_Thread[5027:297367] 3___<NSThread: 0x600000670640>{number = 6, name = (null)}
2018-10-10 15:13:44.479592+0800 Visit_Thread[5027:297365] 1___<NSThread: 0x604000465b80>{number = 4, name = (null)}
2018-10-10 15:13:44.479641+0800 Visit_Thread[5027:297385] 2+++<NSThread: 0x600000670880>{number = 7, name = (null)}
2018-10-10 15:13:47.471226+0800 Visit_Thread[5027:297366] 3+++<NSThread: 0x604000465dc0>{number = 8, name = (null)}
NSOperation的暫停、恢復(fù)和取消
- (IBAction)start:(id)sender {
NSLog(@"start");
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
_queue = queue;
queue.maxConcurrentOperationCount = 1;
[queue addOperationWithBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"1___%@",[NSThread currentThread]);
}
}];
[queue addOperationWithBlock:^{
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2___%@",[NSThread currentThread]);
}
}];
[queue addOperationWithBlock:^{
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3___%@",[NSThread currentThread]);
}
}];
[queue addOperationWithBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"4___%@",[NSThread currentThread]);
}
}];
NSLog(@"end");
}
- (IBAction)suspend:(id)sender {
NSLog(@"暫停");
//不能暫停正在處于執(zhí)行狀態(tài)的任務(wù)
[_queue setSuspended:YES];
}
- (IBAction)goOn:(id)sender {
NSLog(@"繼續(xù)");
[_queue setSuspended:NO];
}
- (IBAction)cancel:(id)sender {
NSLog(@"取消");
//取消之后域庇,不能恢復(fù)
[_queue cancelAllOperations];
}
打印結(jié)果:
2018-10-10 17:05:36.939569+0800 Visit_Thread[6591:388486] start
2018-10-10 17:05:36.940215+0800 Visit_Thread[6591:388486] end
2018-10-10 17:05:38.945240+0800 Visit_Thread[6591:388556] 1___<NSThread: 0x604000462f00>{number = 3, name = (null)}
2018-10-10 17:05:40.948462+0800 Visit_Thread[6591:388556] 1___<NSThread: 0x604000462f00>{number = 3, name = (null)}
2018-10-10 17:05:41.736979+0800 Visit_Thread[6591:388486] 暫停
2018-10-10 17:05:42.948923+0800 Visit_Thread[6591:388556] 1___<NSThread: 0x604000462f00>{number = 3, name = (null)}
2018-10-10 17:06:01.016564+0800 Visit_Thread[6591:388486] 繼續(xù)
2018-10-10 17:06:03.022025+0800 Visit_Thread[6591:388809] 2___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:05.027504+0800 Visit_Thread[6591:388809] 2___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:06.148510+0800 Visit_Thread[6591:388486] 暫停
2018-10-10 17:06:07.028798+0800 Visit_Thread[6591:388809] 2___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:09.031857+0800 Visit_Thread[6591:388809] 2___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:11.032833+0800 Visit_Thread[6591:388809] 2___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:14.879380+0800 Visit_Thread[6591:388486] 繼續(xù)
2018-10-10 17:06:16.882917+0800 Visit_Thread[6591:388809] 3___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:18.885551+0800 Visit_Thread[6591:388809] 3___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:20.889610+0800 Visit_Thread[6591:388809] 3___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:22.890000+0800 Visit_Thread[6591:388809] 3___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:24.893687+0800 Visit_Thread[6591:388809] 3___<NSThread: 0x604000463ec0>{number = 4, name = (null)}
2018-10-10 17:06:26.896813+0800 Visit_Thread[6591:388893] 4___<NSThread: 0x60400026e640>{number = 5, name = (null)}
2018-10-10 17:06:28.898334+0800 Visit_Thread[6591:388893] 4___<NSThread: 0x60400026e640>{number = 5, name = (null)}
2018-10-10 17:06:30.898909+0800 Visit_Thread[6591:388893] 4___<NSThread: 0x60400026e640>{number = 5, name = (null)}
2018-10-10 17:06:32.212768+0800 Visit_Thread[6591:388486] 取消
結(jié)合打印結(jié)果可知:
maxConcurrentOperationCount
為1時(shí)串行執(zhí)行
串行執(zhí)行不等于只開一條線程
不能暫停正在處于執(zhí)行狀態(tài)的任務(wù)
同樣的嵌戈,也不能取消正在執(zhí)行的任務(wù),必須要等當(dāng)前任務(wù)執(zhí)行完畢才能取消
任務(wù)取消之后听皿,便不能恢復(fù)
繼承NSOperation
#import <UIKit/UIKit.h>
@interface DownloadImgOperation : NSOperation
- (instancetype)initWithURL:(NSURL *)url imageView:(UIImageView *)imageView;
@end
#import "DownloadImgOperation.h"
@interface DownloadImgOperation()
@property (strong, nonatomic) NSURL *url;
@property (strong, nonatomic) UIImageView *imageView;
@end
@implementation DownloadImgOperation
- (void)main {//重寫main方法
NSData *data = [[NSData alloc]initWithContentsOfURL:self.url];
UIImage *image = [[UIImage alloc]initWithData:data];
if (image != nil) {
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
}else {
NSLog(@"download error");
}
}
- (instancetype)initWithURL:(NSURL *)url imageView:(UIImageView *)imageView {
if (self = [super init]) {
self.imageView = imageView;
self.url = url;
}
return self;
}
- (void)updateUI:(UIImage *)image {
self.imageView.image =image;
}
@end
如果是在自定義Operation中的main方法中有耗時(shí)操作熟呛,那么需要特別處理:
- (void)main {//重寫main方法
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"1___%@",[NSThread currentThread]);
}
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2___%@",[NSThread currentThread]);
}
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3___%@",[NSThread currentThread]);
}
}
調(diào)用注意點(diǎn):
1、暫定功能不起作用尉姨,因?yàn)闀和J轻槍?duì)多個(gè)Operation
的庵朝,開始時(shí)只有一個(gè),暫停時(shí)需要等這個(gè)Operation
執(zhí)行完畢又厉,所以沒有意義九府,取消也是如此。那么繼續(xù)也便沒有意義覆致。
2侄旬、但是可以實(shí)現(xiàn)通過改進(jìn),來實(shí)現(xiàn)取消功能(在main
方法中做更改):
- (IBAction)start:(id)sender {
NSLog(@"start");
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
_queue = queue;
queue.maxConcurrentOperationCount = 1;
DownloadImgOperation *operation = [[DownloadImgOperation alloc]init];
[_queue addOperation:operation];
NSLog(@"end");
}
- (IBAction)cancel:(id)sender {
NSLog(@"取消");
[_queue cancelAllOperations];
}
更改main
方法:
- (void)main {//重寫main方法
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
//雖然在此處可以做到精確控制篷朵,但是如果循環(huán)次數(shù)太多勾怒,每次都需要做判斷婆排,所以不建議這樣使用
// if(self.isCancelled) return;
NSLog(@"1___%@",[NSThread currentThread]);
}
if(self.isCancelled) return;
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"2___%@",[NSThread currentThread]);
}
if(self.isCancelled) return;
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:2];
NSLog(@"3___%@",[NSThread currentThread]);
}
}
設(shè)置NSOperation的依賴與監(jiān)聽
- (IBAction)start:(id)sender {
NSLog(@"start");
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
NSOperationQueue *queue2 = [[NSOperationQueue alloc]init];
NSBlockOperation *task1 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:1];
NSLog(@"1___%@",[NSThread currentThread]);
}
}];
NSBlockOperation *task2 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:1];
NSLog(@"2___%@",[NSThread currentThread]);
}
}];
NSBlockOperation *task3 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 5; i++) {
[NSThread sleepForTimeInterval:1];
NSLog(@"3___%@",[NSThread currentThread]);
}
}];
NSBlockOperation *task4 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 3; i++) {
[NSThread sleepForTimeInterval:1];
NSLog(@"4___%@",[NSThread currentThread]);
}
}];
//設(shè)置依賴:
//
[task2 addDependency:task1];//必須等task1的任務(wù)執(zhí)行完畢task2才能執(zhí)行
[task3 addDependency:task2];//必須等task2的任務(wù)執(zhí)行完畢task3才能執(zhí)行
task1.completionBlock = ^ {
NSLog(@"task1執(zhí)行完畢了————%@",[NSThread currentThread]);
};
[queue addOperation:task1];
[queue2 addOperation:task2];
[queue2 addOperation:task3];
[queue addOperation:task4];
NSLog(@"end");
}
打印結(jié)果:
2018-10-10 18:25:08.234783+0800 Visit_Thread[7925:466651] start
2018-10-10 18:25:08.235548+0800 Visit_Thread[7925:466651] end
2018-10-10 18:25:09.238803+0800 Visit_Thread[7925:466803] 4___<NSThread: 0x600000478880>{number = 4, name = (null)}
2018-10-10 18:25:09.238801+0800 Visit_Thread[7925:466707] 1___<NSThread: 0x600000476900>{number = 3, name = (null)}
2018-10-10 18:25:10.242784+0800 Visit_Thread[7925:466803] 4___<NSThread: 0x600000478880>{number = 4, name = (null)}
2018-10-10 18:25:10.242784+0800 Visit_Thread[7925:466707] 1___<NSThread: 0x600000476900>{number = 3, name = (null)}
2018-10-10 18:25:11.247918+0800 Visit_Thread[7925:466803] 4___<NSThread: 0x600000478880>{number = 4, name = (null)}
2018-10-10 18:25:11.247918+0800 Visit_Thread[7925:466707] 1___<NSThread: 0x600000476900>{number = 3, name = (null)}
2018-10-10 18:25:11.248278+0800 Visit_Thread[7925:466707] task1執(zhí)行完畢了————<NSThread: 0x600000476900>{number = 3, name = (null)}
2018-10-10 18:25:12.248466+0800 Visit_Thread[7925:466810] 2___<NSThread: 0x60000047f3c0>{number = 5, name = (null)}
2018-10-10 18:25:13.252236+0800 Visit_Thread[7925:466810] 2___<NSThread: 0x60000047f3c0>{number = 5, name = (null)}
2018-10-10 18:25:14.256300+0800 Visit_Thread[7925:466810] 2___<NSThread: 0x60000047f3c0>{number = 5, name = (null)}
2018-10-10 18:25:15.261807+0800 Visit_Thread[7925:466810] 2___<NSThread: 0x60000047f3c0>{number = 5, name = (null)}
2018-10-10 18:25:16.267055+0800 Visit_Thread[7925:466810] 2___<NSThread: 0x60000047f3c0>{number = 5, name = (null)}
2018-10-10 18:25:17.267466+0800 Visit_Thread[7925:466707] 3___<NSThread: 0x600000476900>{number = 3, name = (null)}
2018-10-10 18:25:18.272417+0800 Visit_Thread[7925:466707] 3___<NSThread: 0x600000476900>{number = 3, name = (null)}
2018-10-10 18:25:19.275128+0800 Visit_Thread[7925:466707] 3___<NSThread: 0x600000476900>{number = 3, name = (null)}
2018-10-10 18:25:20.280244+0800 Visit_Thread[7925:466707] 3___<NSThread: 0x600000476900>{number = 3, name = (null)}
2018-10-10 18:25:21.281868+0800 Visit_Thread[7925:466707] 3___<NSThread: 0x600000476900>{number = 3, name = (null)}
NSOperation的線程間的通信
1声旺、方式1
- (IBAction)start:(id)sender {
NSLog(@"start");
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
// [queue addOperationWithBlock:^{
// //coding
// }];
__block UIImage *img ;
NSBlockOperation *task = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@"http://c.hiphotos.baidu.com/image/h%3D300/sign=c635d3753efa828bce239be3cd1f41cd/0eb30f2442a7d933b29eb303a04bd11373f0018f.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
img = [UIImage imageWithData:data];
}];
task.completionBlock = ^ {
NSLog(@"task1執(zhí)行完畢了————%@",[NSThread currentThread]);
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
self.imgView.image = img;
}];
};
[queue addOperation:task];
NSLog(@"end");
}
2、方式2
- (IBAction)start:(id)sender {
NSLog(@"start");
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperationWithBlock:^{
//coding
NSLog(@"%@",[NSThread currentThread]);
}];
__block UIImage *img ;
NSBlockOperation *task = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@"http://c.hiphotos.baidu.com/image/h%3D300/sign=c635d3753efa828bce239be3cd1f41cd/0eb30f2442a7d933b29eb303a04bd11373f0018f.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [UIImage imageWithData:data];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
self.imgView.image = img;
}];
}];
[queue addOperation:task];
NSLog(@"end");
}
練習(xí):將2張圖片合成一張圖片并展示
- (IBAction)start:(id)sender {
NSLog(@"start");
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
__block UIImage *img1 ;
NSBlockOperation *task1 = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@"http://c.hiphotos.baidu.com/image/h%3D300/sign=c635d3753efa828bce239be3cd1f41cd/0eb30f2442a7d933b29eb303a04bd11373f0018f.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
img1 = [UIImage imageWithData:data];
}];
__block UIImage *img2 ;
NSBlockOperation *task2 = [NSBlockOperation blockOperationWithBlock:^{
NSURL *url = [NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/h%3D300/sign=b48b76f776899e51678e3c1472a6d990/e824b899a9014c08ef778daf077b02087bf4f468.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
img2 = [UIImage imageWithData:data];
}];
NSBlockOperation *task3 = [NSBlockOperation blockOperationWithBlock:^{
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
[img1 drawInRect:CGRectMake(0, 0, 200, 100)];
[img2 drawInRect:CGRectMake(0, 100, 200, 100)];
UIImage *combinImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
self.imgView.image = combinImg;
}];
}];
[task3 addDependency:task1];
[task3 addDependency:task2];
[queue addOperation:task1];
[queue addOperation:task2];
[queue addOperation:task3];
NSLog(@"end");
}