iOS開發(fā)常常會(huì)碰到多線程開發(fā)技術(shù),我們常用的集中多線程開發(fā)的技術(shù)有一下幾點(diǎn):
(1)pThread進(jìn)行開發(fā),pthread是基于C語(yǔ)言稽亏;
(2)NSThread 進(jìn)行開辟多線程方式;
(3)GCD ;
(4)NSOperation.
接下來(lái)對(duì)上面幾種多線程技術(shù)進(jìn)行詳細(xì)的講解:
一.pThread
(1) pThread的創(chuàng)建線程方式
pthread_t thread;
pthread_create(&thread, NULL, run, NULL);
//run是需要在子線程實(shí)現(xiàn)的方法。
void *run(void *data){
NSLog(@"我在子線程中執(zhí)行……");
for (int i = 1; i < 10 ; i ++) {
NSLog(@"%d",i);
sleep(1);
}
return NULL;
}
2.NSThread 創(chuàng)建線程有三種方式
(1)方式一 NSThread *thread1 = [[NSThread alloc] initWithTarget:self
selector:@selector(runNSThread1) object:nil];
thread1.name = @"Name_thread1"; //設(shè)置線程的識(shí)別名
[thread1 setThreadPriority:0.7]; //設(shè)置優(yōu)先級(jí)別
[thread1 start];
//runNSThread1 是在子線程里呕臂,執(zhí)行的方法。
在子線程里肪跋,怎么回到主線程的方法需要調(diào)用 [self performSelectorOnMainThread:@selector(runMainThread) withObject:nil waitUntilDone:YES];回到主線程執(zhí)行的方法runMainThread這個(gè)方法內(nèi)部就是在主線程執(zhí)行了歧蒋。
(2)方式二 通過(guò)detachNewThreadSelector方式創(chuàng)建并執(zhí)行線程
[NSThread detachNewThreadSelector:@selector(runNSThread1) toTarget:self withObject:nil];
(3)方式三 通過(guò)performSelectorInBackground方式創(chuàng)建并執(zhí)行線程
[self performSelectorInBackground:@selector(runNSThread1) withObject:nil];
獲取當(dāng)前線程的信息 [NSThread currentThread].name ;
3.GCD
(1)dispatch_async創(chuàng)建一個(gè)線程
// dispatch_async(dispatch_get_global_queue(0, 0), ^{
// //執(zhí)行耗時(shí)任務(wù)
// NSLog(@"start task 1");
// [NSThread sleepForTimeInterval:2];
// NSLog(@"end task 1");
// dispatch_async(dispatch_get_main_queue(), ^{
// //刷新UI
// NSLog(@"回到主線程,刷新UI");
// });
// });
(2)多線程的線程的優(yōu)先級(jí)別
//dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
// //執(zhí)行耗時(shí)任務(wù)
// NSLog(@"start task 1");
// [NSThread sleepForTimeInterval:2];
// NSLog(@"end task 1");
// });
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
// NSLog(@"start task 2");
// [NSThread sleepForTimeInterval:2];
// NSLog(@"end task 2");
// });
// dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// //執(zhí)行耗時(shí)任務(wù)
// NSLog(@"start task 3");
// [NSThread sleepForTimeInterval:2];
// NSLog(@"end task 3");
// });
DISPATCH_QUEUE_PRIORITY_HIGH
DISPATCH_QUEUE_PRIORITY_LOW
DISPATCH_QUEUE_PRIORITY_DEFAULT
是優(yōu)先級(jí)別的參數(shù)州既。
(3)dispatch_queue_t 創(chuàng)建異步執(zhí)行和串行執(zhí)行queue
dispatch_queue_t queue = dispatch_queue_create("com.text.cn", DISPATCH_QUEUE_CONCURRENT);
// //NULL 為串行的 其實(shí)在同一個(gè)線程里執(zhí)行的= DISPATCH_QUEUE_SERIAL
// //DISPATCH_QUEUE_CONCURRENT - 為異步執(zhí)行
// dispatch_async(queue, ^{
// //執(zhí)行耗時(shí)任務(wù)
// NSLog(@"start task 1");
// [NSThread sleepForTimeInterval:2];
// NSLog(@"end task 1");
// });
// dispatch_async(queue, ^{
// //執(zhí)行耗時(shí)任務(wù)
// NSLog(@"start task 2");
// [NSThread sleepForTimeInterval:2];
// NSLog(@"end task 2");
// });
// dispatch_async(queue, ^{
// //執(zhí)行耗時(shí)任務(wù)
// NSLog(@"start task 3");
// [NSThread sleepForTimeInterval:2];
// NSLog(@"end task 3");
// });
//NULL 為串行的 其實(shí)在同一個(gè)線程里執(zhí)行的= DISPATCH_QUEUE_SERIAL
// //DISPATCH_QUEUE_CONCURRENT - 為異步執(zhí)行
(4)dispatch_group_t 執(zhí)行一定的任務(wù)谜洽,可以用dispatch_group_notify接收所有的任務(wù)執(zhí)行完的一個(gè)后續(xù)操作,當(dāng)前現(xiàn)在在最后一個(gè)執(zhí)行完的線程里操作吴叶,需要回到主線程來(lái)操作
dispatch_queue_t queue1 = dispatch_queue_create("com.cn.ctvit.reque", DISPATCH_QUEUE_CONCURRENT); //異步
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue1, ^{
//內(nèi)部可以執(zhí)行異步操作阐虚,當(dāng)前不是異步操作,如果是異步操作試一試
NSLog(@"start task 1");
[NSThread sleepForTimeInterval:2];
NSLog(@"end task 1");
});
dispatch_group_async(group, queue1, ^{
NSLog(@"start task 2");
[NSThread sleepForTimeInterval:2];
NSLog(@"end task 2");
});
dispatch_group_async(group, queue1, ^{
NSLog(@"start task 3");
[NSThread sleepForTimeInterval:2];
NSLog(@"end task 3");
});
dispatch_group_notify(group, queue1, ^{
NSLog(@"all task done");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回到主線程");
});
});
(5)GCD實(shí)現(xiàn)單例
(6)GCD實(shí)現(xiàn)延遲操作
//延遲執(zhí)行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (2*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"dely excute");
});
4.NSInvocationOperation蚌卤,NSBlockOperation实束,NSOperation和NSOperationqueue 的組合運(yùn)用
(1)NSInvocationOperation
//同步執(zhí)行-放主線程里則會(huì)阻塞主線程,放在子線程則會(huì)阻塞子線程
// NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(goInvocation) object:nil];
// [invocation start];
//創(chuàng)建一個(gè)子線程-則阻塞子線程
// dispatch_async(dispatch_get_global_queue(0, 0), ^{
// NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(goInvocation) object:nil];
// [invocation start];
// });
(2)NSBlockOperation
//同步執(zhí)行
// NSBlockOperation *blockOpration = [NSBlockOperation blockOperationWithBlock:^{
// for (int i = 0; i < 3; i ++) {
// NSLog(@"start task");
// [NSThread sleepForTimeInterval:2];
// }
// }];
// [blockOpration start];
(3)NSOperation 和 NSOperationQueue
if (!self.oprQueue) {
self.oprQueue = [[NSOperationQueue alloc] init];
}
[self.oprQueue setMaxConcurrentOperationCount:4];
CustomOperation *operationA = [[CustomOperation alloc] initWithName:@"operationA"];
CustomOperation *operationB = [[CustomOperation alloc] initWithName:@"operationB"];
CustomOperation *operationC = [[CustomOperation alloc] initWithName:@"operationC"];
CustomOperation *operationD = [[CustomOperation alloc] initWithName:@"operationD"];
[operationD addDependency:operationA];
[operationA addDependency:operationB];
[operationB addDependency:operationC]; //依賴關(guān)系不能相互依賴逊彭,也就是循環(huán)依賴
//異步執(zhí)行
[self.oprQueue addOperation:operationA];
[self.oprQueue addOperation:operationB];
[self.oprQueue addOperation:operationC];
[self.oprQueue addOperation:operationD];
//CustomOperation是繼承NSOperation 重寫了main函數(shù)執(zhí)行的咸灿。