一、概念
NSOperation是一個(gè)多線程任務(wù)季希。NSOperation有NSInvocationOperation丁恭、NSBlockOperation兩個(gè)子類。
NSOperationQueue負(fù)責(zé)管理多個(gè)NSOperation,它是個(gè)FIFO隊(duì)列谚中,會(huì)按順序啟動(dòng)線程執(zhí)行NSOperation任務(wù)。
二、用法
NSOperation實(shí)現(xiàn)多線程有兩個(gè)方式宪塔,一個(gè)是直接使用NSInvocationOperation磁奖、NSBlockOperation兩個(gè)子類,一個(gè)是自己實(shí)現(xiàn)NSOperation的子類某筐。在平時(shí)的開發(fā)中掌握第一種的使用基本上能夠應(yīng)對(duì)大部分多線程需求比搭。這里主要講解第一種使用
一、直接使用NSInvocationOperation和NSBlockOperation
NSInvocationOperation 是通過方法實(shí)現(xiàn)的形式完成多線程任務(wù)南誊。
NSInvocationOperation*invocationOperation = [[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(invocationOperationAction)object:nil];
NSBlockOperation是通過代碼塊的形式完成多線程任務(wù)身诺。
NSBlockOperation*blockOperation = [NSBlockOperationblockOperationWithBlock:^{
}];
? ? 執(zhí)行任務(wù)有兩個(gè)方式,一個(gè)是用start方法 一個(gè)是提交到NSOperationQueue, 用start 方法時(shí)與主線程同步抄囚,有阻塞主線程的情況,提交到NSOperationQueue中與主線程是異步霉赡,不會(huì)阻塞到主線程。
? ?NSOperationQueue可以通過maxConcurrentOperationCount設(shè)置線程最大并行數(shù)量怠苔,為1的時(shí)候相當(dāng)于串行同廉,大于1時(shí)為并發(fā)。
Talk is Cheap,show you the code:
- (void)viewDidLoad {
[superviewDidLoad];
UILabel*label= [[UILabelalloc]init];
label.frame=CGRectMake(40,40,100,20);
label.text=@"頁面已經(jīng)顯示";
[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);
}
//異步加載圖片時(shí)要到主線程顯示
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];
}
}];
//----------------執(zhí)行任務(wù)方式一:用start方法------------------
/**用start執(zhí)行線程任務(wù)時(shí)為同步效果柑司,blockOperation、invocationOperation阻塞主線程
*要等到blockOperation锅劝、invocationOperation兩個(gè)線程任務(wù)執(zhí)行完畢之后self.view的背景色才會(huì)變?yōu)辄S色
//*/
//NSLog(@"沒有變色"); //這句話一開始就會(huì)打印出來攒驰,而label和imgView要等兩個(gè)operation后才顯示出來。因?yàn)閁I要在主線程上渲染后顯示故爵,start阻塞了主線程玻粪。
//[blockOperation start];
//[invocationOperation start];
//NSLog(@"變色");
//self.view.backgroundColor = [UIColor yellowColor];
//---------------執(zhí)行任務(wù)方式二:加入NSOperationQueue (兩種方式運(yùn)行的時(shí)候要注釋掉其中一種) -----------
//線程任務(wù)與主線程異步,不會(huì)阻塞主線程诬垂,self.view的顏色一開始就變?yōu)辄S色
NSOperationQueue*queue = [[NSOperationQueuealloc]init];
//設(shè)置最大的線程并行數(shù)量如果為1的話就相當(dāng)于串行劲室,大于1時(shí)為并行
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;
}
三、總結(jié)
1结窘、有NSBlockOperation 和 NSInvocationOperation 兩種方式實(shí)現(xiàn)多線程任務(wù)很洋;
2、有兩種方式執(zhí)行任務(wù) :一個(gè)是start方法隧枫,一個(gè)是提交到NSOperationQueue喉磁,前者是同步,后者是異步官脓。
3协怒、NSOperationQueue可以通過設(shè)置最大線程并發(fā)數(shù)量來決定串行或并發(fā)。