實(shí)現(xiàn)多線程的方式一般有三種:NSThread、GCD叹侄、NSOperation
1巩搏、NSThread:適用簡(jiǎn)單,簡(jiǎn)單易用,可以直接操作線程趾代,oc 的贯底,偶爾使用,程序員管理生命周期
//1.1 創(chuàng)建線程
//實(shí)例方法:創(chuàng)建線程后需手動(dòng)開啟線程
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument撒强;
//demo
NSThread* myThread = [[NSThread alloc] initWithTarget:self
selector:@selector(doSomething:)
object:nil];
[myThread start];
//類方法:創(chuàng)建完成后直接運(yùn)行線程
+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument禽捆;
//demo
[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];
//通知主線程更新UI
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
//1.2 鎖
NSLock *theLock = [[NSLock alloc] init];
//上鎖
[theLock lock];
//解鎖
[theLock unlock];
2、GCD:替代 NSThread 等多線程技術(shù)飘哨,充分利用設(shè)備多核技術(shù)胚想,c的,經(jīng)常使用芽隆,系統(tǒng)自動(dòng)管理線程生命周期
//1浊服、常用的方法dispatch_async
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 耗時(shí)的操作
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
});
});
//2、dispatch_group_async的使用
//dispatch_group_async可以實(shí)現(xiàn)監(jiān)聽一組任務(wù)是否完成胚吁,完成后得到通知執(zhí)行其他的操作牙躺。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"group1");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"group2");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"group3");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"updateUi");
});
dispatch_release(group);
//當(dāng)三個(gè)線程都完成之后,group才會(huì)執(zhí)行
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
});
//中的方法
//3腕扶、dispatch_barrier_async的使用
//dispatch_barrier_async是在前面的任務(wù)執(zhí)行結(jié)束后它才執(zhí)行孽拷,而且它后面的任務(wù)等它執(zhí)行完成之后才會(huì)執(zhí)行
//demo
dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"dispatch_async1");
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:4];
NSLog(@"dispatch_async2");
});
dispatch_barrier_async(queue, ^{
NSLog(@"dispatch_barrier_async");
[NSThread sleepForTimeInterval:4];
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"dispatch_async3");
});
//運(yùn)行結(jié)果
//dispatch_async1
//dispatch_async2
//dispatch_barrier_async
//dispatch_async3
//4、dispatch_apply 使用
重復(fù)執(zhí)行同一段代碼蕉毯。
dispatch_apply(5, globalQ, ^(size_t index) {
// 執(zhí)行5次
});
3乓搬、NSOperation:基于 gcd 的封裝,比 gcd 簡(jiǎn)單代虾,更加面向?qū)ο蠼希到y(tǒng)自動(dòng)管理線程生命周期,經(jīng)常使用
- (void)viewDidLoad
{
[super viewDidLoad];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperation:operation];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)downloadImage:(NSString *)url{
NSLog(@"url:%@", url);
NSURL *nsUrl = [NSURL URLWithString:url];
NSData *data = [[NSData alloc]initWithContentsOfURL:nsUrl];
UIImage * image = [[UIImage alloc]initWithData:data];
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
}
-(void)updateUI:(UIImage*) image{
self.imageView.image = image;
}
//n建一個(gè)NSInvocationOperatio線程棉磨,并且放到NSOperationQueue中江掩。后臺(tái)線程執(zhí)行downloadImage方法。方法完成后用performSelectorOnMainThread執(zhí)行主線程updateUI方法乘瓤。
//加入到NSOperationQueue的線程默認(rèn)全部同時(shí)進(jìn)行环形。若想做限制,可用此方法
[queue setMaxConcurrentOperationCount:5];
//默認(rèn)為-1衙傀,即無限制