NSThread####
(每個NSThread對象對應(yīng)一個線程算撮,真正的多線程)
-
使用NSObject類的方法performSelectorInBackground:withObject:來創(chuàng)建一個線程譬巫。
[Object performSelectorInBackground:@selector(doSomething:) withObject:nil];對應(yīng)的在主線程上調(diào)用的方法的(更新UI必須回到主線程): [Object performSelectorOnMainThread:@selector(doSomething:) withObject:nil waitUntilDone:NO];
-
選擇使用NSThread實現(xiàn)多線程庞溜。
NSThread創(chuàng)建主要有兩種方式:1:[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil]; 2:NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil]; [myThread start]; 這兩種方式的區(qū)別在于: 前一種調(diào)用就會立即創(chuàng)建一個線程并執(zhí)行selector方法赖淤;第二種方式盡管alloc了一個新Thread管搪, 但需要手動調(diào)用start方法來啟動線程谆构。這點與Java創(chuàng)建線程的方式相似裸扶。 第一種方式,與上述做法1使用NSObject的類方法performSelectorInBackground:withObject:是一樣的搬素; 第二種方式的可以在start真正創(chuàng)建線程之前對其進行設(shè)置呵晨,比如設(shè)置線程的優(yōu)先級。
還有要注意的是在多個線程都在執(zhí)行同一個方法的時候要使用線程鎖NSLock
我們可以使用指令 @synchronized 來簡化 NSLock的使用熬尺,這樣我們就不必顯示編寫創(chuàng)建NSLock,加鎖并解鎖相關(guān)代碼摸屠。
- (void)doSomeThing:(id)anObj{
@synchronized(anObj) {
// Everything between the braces is protected by the @synchronized directive.
}}
Grand Central Dispatch (GCD)####
The main queue:主隊列,串行隊列
main queue可以調(diào)用dispatch_get_main_queue()來獲得粱哼。因為main queue是與主線程相關(guān)的季二,所以這是一個串行隊列。
dispatch_async(dispatch_get_main_queue(), ^{ // something });Global queues: 全局隊列皂吮,并發(fā)隊列(后臺執(zhí)行)
進程中存在三個全局隊列:高戒傻、中(默認(rèn))、低三個優(yōu)先級隊列(實際還有一個更低優(yōu)先級為DISPATCH_QUEUE_PRIORITY_BACKGROUND)蜂筹⌒枘桑可以調(diào)用dispatch_get_global_queue函數(shù)傳入優(yōu)先級來訪問隊列。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // something });
***需要注意的是艺挪,三個隊列不代表三個線程不翩,可能會有更多的線程。并發(fā)隊列可以根據(jù)實際情況來自動產(chǎn)生合理的線程數(shù)麻裳,也可理解為dispatch隊列實現(xiàn)了一個線程池的管理口蝠,對于程序邏輯是透明的。 ***
-
用戶隊列
用戶隊列 (GCD并不這樣稱呼這種隊列, 但是沒有一個特定的名字來形容這種隊列津坑,所以我們稱其為用戶隊列) 是用函數(shù) dispatch_queue_create創(chuàng)建的隊列. 這些隊列是串行的妙蔗。dispatch_queue_t queue = dispatch_queue_create("com.dispatch.serial", DISPATCH_QUEUE_SERIAL); dispatch_async(queue, ^{ // something }); //生成一個串行隊列,隊列中的block按照先進先出(FIFO)的順序去執(zhí)行疆瑰,實際上為單線程執(zhí)行眉反。第一個參數(shù)是隊列的名稱昙啄,在調(diào)試程序時會非常有用,所有盡量不要重名了寸五。 dispatch_queue_t queue = dispatch_queue_create("com.dispatch.concurrent", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ // something }); //生成一個并發(fā)執(zhí)行隊列梳凛,block被分發(fā)到多個線程去執(zhí)行 例子:多線程寫同一數(shù)據(jù)庫,需要保持寫入的順序和每次寫入的完整性梳杏,簡單地利用串行隊列即可實現(xiàn): dispatch_queue_t queue1 = dispatch_queue_create("com.dispatch.writedb", DISPATCH_QUEUE_SERIAL); - (void)writeDB:(NSData *)data { dispatch_async(queue1, ^{ //write database }); } 下一次調(diào)用writeDB:必須等到上次調(diào)用完成后才能進行韧拒,保證writeDB:方法是線程安全的。