一、概念
NSOperation是一個多執行緒任務。NSOperation有NSInvocationOperation、NSBlockOperation兩個子類。
NSOperationQueue負責管理多個NSOperation,它是個FIFO佇列,會按順序啟動執行緒執行NSOperation任務。
二、用法
NSOperation實現多執行緒有兩個方式,一個是直接使用NSInvocationOperation、NSBlockOperation兩個子類,一個是自己實現NSOperation的子類。在平時的開發中掌握第一種的使用基本上能夠應對大部分多執行緒需求。這裡主要講解第一種使用
一、直接使用NSInvocationOperation和NSBlockOperation
NSInvocationOperation 是通過方法實現的形式完成多執行緒任務。
NSInvocationOperation*invocationOperation = [[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(invocationOperationAction)object:nil];
NSBlockOperation是通過程式碼塊的形式完成多執行緒任務。
NSBlockOperation*blockOperation = [NSBlockOperationblockOperationWithBlock:^{
}];
執行任務有兩個方式,一個是用start方法 一個是提交到NSOperationQueue, 用start 方法時與主執行緒同步,有阻塞主執行緒的情況,提交到NSOperationQueue中與主執行緒是非同步,不會阻塞到主執行緒。
NSOperationQueue可以通過maxConcurrentOperationCount設定執行緒最大並行數量,為1的時候相當於序列,大於1時為併發。
Talk is Cheap,show you the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
- (void)viewDidLoad { [superviewDidLoad]; UILabel*label= [[UILabelalloc]init]; label.frame=CGRectMake(40,40,100,20); label.text=@"頁面已經顯示"; [self.viewaddSubview:label]; self.imgView= [[UIImageViewalloc]init]; self.imgView.frame=CGRectMake(30,30,50,50); self.imgView.backgroundColor= [UIColorredColor]; [self.viewaddSubview:self.imgView]; NSInvocationOperation*invocationOperation = [[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(invocationOperationAction)object:nil]; __weakViewController*weakSelf =self; NSBlockOperation*blockOperation = [NSBlockOperationblockOperationWithBlock:^{ for(inti =0; i <3; i++) { [NSThreadsleepForTimeInterval:0.5]; NSLog(@"執行緒block--%d",i); } //非同步載入圖片時要到主執行緒顯示 NSURL*url = [NSURLURLWithString:@"https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1459910345&di=297c58ac877a35d5cd21f1b12e25ddf0&src=http://a.hiphotos.baidu.com/lvpics/w=1000/sign=c9a07988672762d0803ea0bf90dc09fa/359b033b5bb5c9ea7582c548d139b6003af3b32c.jpg"]; NSData*data = [[NSDataalloc]initWithContentsOfURL:url]; UIImage*img = [[UIImagealloc]initWithData:data]; if(img) { [weakSelfperformSelectorOnMainThread:@selector(updateImgView:)withObject:imgwaitUntilDone:YES]; } }]; //----------------執行任務方式一:用start方法------------------ /**用start執行執行緒任務時為同步效果,blockOperation、invocationOperation阻塞主執行緒 *要等到blockOperation、invocationOperation兩個執行緒任務執行完畢之後self.view的背景色才會變為黃色 //*/ //NSLog(@"沒有變色"); //這句話一開始就會列印出來,而label和imgView要等兩個operation後才顯示出來。因為UI要在主執行緒上渲染後顯示,start阻塞了主執行緒。 //[blockOperation start]; //[invocationOperation start]; //NSLog(@"變色"); //self.view.backgroundColor = [UIColor yellowColor]; //---------------執行任務方式二:加入NSOperationQueue (兩種方式執行的時候要註釋掉其中一種) ----------- //執行緒任務與主執行緒非同步,不會阻塞主執行緒,self.view的顏色一開始就變為黃色 NSOperationQueue*queue = [[NSOperationQueuealloc]init]; //設定最大的執行緒並行數量如果為1的話就相當於序列,大於1時為並行 queue.maxConcurrentOperationCount=2; [queueaddOperation:blockOperation]; [queueaddOperation:invocationOperation]; self.view.backgroundColor= [UIColoryellowColor]; } -(void)invocationOperationAction { for(inti =0; i <5; i++) { [NSThreadsleepForTimeInterval:0.5]; NSLog(@"執行緒invocation--%d",i); } } - (void)updateImgView:(UIImage*)image { self.imgView.image= image; } |
三、總結
1、有NSBlockOperation 和 NSInvocationOperation 兩種方式實現多執行緒任務;
2、有兩種方式執行任務 :一個是start方法,一個是提交到NSOperationQueue,前者是同步,後者是非同步。
3、NSOperationQueue可以通過設定最大執行緒併發數量來決定序列或併發。
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!
任選一種支付方式