在iOS中每個(gè)進(jìn)程啟動(dòng)后都會(huì)建立一個(gè)主線程(UI線程),這個(gè)線程是其他線程的父線程。由于在iOS中除了主線程,其他子線程是獨(dú)立于Cocoa Touch的,所以只有主線程可以更新UI界面(新版iOS中,使用其他線程更新UI可能也能成功,但是不推薦)。iOS中多線程使用并不復(fù)雜,關(guān)鍵是如何控制好各個(gè)線程的執(zhí)行順序、處理好資源競(jìng)爭(zhēng)問(wèn)題。常用的多線程開(kāi)發(fā)有三種方式:
1.NSThread
2.GCD
3.NSOperation
第一種方式:NSThread
使用NSThread開(kāi)啟一個(gè)線程有兩種方法
//該方法開(kāi)啟的線程會(huì)立即執(zhí)行
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument
//改方法創(chuàng)建的新的線程,需要調(diào)用start方法啟動(dòng)線程后,才執(zhí)行新的線程
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument
第二種方法: GCD簡(jiǎn)介
//異步執(zhí)行 + 并行隊(duì)列
- (void)asyncConcurrent{
//創(chuàng)建一個(gè)并行隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("標(biāo)識(shí)符", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"---start---");
//使用異步函數(shù)封裝三個(gè)任務(wù)
dispatch_async(queue, ^{
NSLog(@"任務(wù)1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)3---%@", [NSThread currentThread]);
});
NSLog(@"---end---");
}
打印結(jié)果
---start---
---end---
任務(wù)3---{number = 5, name = (null)}
任務(wù)2---{number = 4, name = (null)}
任務(wù)1---{number = 3, name = (null)}
2.異步執(zhí)行 + 串行隊(duì)列
//異步執(zhí)行 + 串行隊(duì)列
- (void)asyncSerial{
//創(chuàng)建一個(gè)串行隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("標(biāo)識(shí)符", DISPATCH_QUEUE_SERIAL);
NSLog(@"---start---");
//使用異步函數(shù)封裝三個(gè)任務(wù)
dispatch_async(queue, ^{
NSLog(@"任務(wù)1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)3---%@", [NSThread currentThread]);
});
NSLog(@"---end---");
}
打印結(jié)果:
---start---
---end---
任務(wù)1---{number = 3, name = (null)}
任務(wù)2---{number = 3, name = (null)}
任務(wù)3---{number = 3, name = (null)}
3.同步執(zhí)行 + 并行隊(duì)列
//同步執(zhí)行 + 并行隊(duì)列
- (void)syncConcurrent{
//創(chuàng)建一個(gè)并行隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("標(biāo)識(shí)符", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"---start---");
//使用同步函數(shù)封裝三個(gè)任務(wù)
dispatch_sync(queue, ^{
NSLog(@"任務(wù)1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"任務(wù)2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"任務(wù)3---%@", [NSThread currentThread]);
});
NSLog(@"---end---");
}
打印結(jié)果:
---start---
任務(wù)1---{number = 1, name = main}
任務(wù)2---{number = 1, name = main}
任務(wù)3---{number = 1, name = main}
---end---
4.同步執(zhí)行+ 串行隊(duì)列
- (void)syncSerial{
//創(chuàng)建一個(gè)串行隊(duì)列
dispatch_queue_t queue = dispatch_queue_create("標(biāo)識(shí)符", DISPATCH_QUEUE_SERIAL);
NSLog(@"---start---");
//使用異步函數(shù)封裝三個(gè)任務(wù)
dispatch_sync(queue, ^{
NSLog(@"任務(wù)1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"任務(wù)2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"任務(wù)3---%@", [NSThread currentThread]);
});
NSLog(@"---end---");
}
打印結(jié)果:
---start---
任務(wù)1---{number = 1, name = main}
任務(wù)2---{number = 1, name = main}
任務(wù)3---{number = 1, name = main}
---end---
5.異步執(zhí)行+主隊(duì)列
- (void)asyncMain{
//獲取主隊(duì)列
dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@"---start---");
//使用異步函數(shù)封裝三個(gè)任務(wù)
dispatch_async(queue, ^{
NSLog(@"任務(wù)1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)3---%@", [NSThread currentThread]);
});
NSLog(@"---end---");
}
打印結(jié)果:
---start---
---end---
任務(wù)1---{number = 1, name = main}
任務(wù)2---{number = 1, name = main}
任務(wù)3---{number = 1, name = main}
6.常用的在耗時(shí)操作,重新開(kāi)一個(gè)線程,然后在主線程中刷新UI
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
//耗時(shí)的操作 dispatch_async(dispatch_get_main_queue(), ^{
//在主線程中執(zhí)行回調(diào)
});
}
});