線程是進(jìn)程的組成單位 線程是一段可重復(fù)使用的代碼塊
一個(gè)線程同一時(shí)間只能完成一個(gè)任務(wù)
一個(gè)線程執(zhí)行多任務(wù)時(shí) 串行執(zhí)行
異步數(shù)據(jù)請(qǐng)求使用的都是多線程 多個(gè)線程同時(shí)工作互不影響 并發(fā)
線程
主線程:UI線程 由編譯器自動(dòng)創(chuàng)建 不能修改 MAinThread
工作線程:次線程 有程序員創(chuàng)建 可隨意修改 workThread/secondThread
[原因]主線程在一定時(shí)間的范圍內(nèi)重復(fù)執(zhí)行某個(gè)動(dòng)作(重復(fù)調(diào)用某個(gè)函數(shù))出現(xiàn)屏幕假死 一定時(shí)間后屏幕才能恢復(fù)與用戶(hù)交互的效果 -- 解決方法 使用工作線程(工作線程完成重復(fù)操作)
線程的可行方式:
NSThread
NSOperationQueue
GCD
多線程
1.NSThread
創(chuàng)建線程方式有兩種
使用類(lèi)方法創(chuàng)建線程對(duì)象
類(lèi)方法創(chuàng)建的線程對(duì)象 不需要開(kāi)啟 直接就會(huì)執(zhí)行SEL:函數(shù)
[NSThread detachNewThreadSelector:<#(nonnull SEL)#> toTarget:<#(nonnull id)#> withObject:<#(nullable id)#>]
使用實(shí)例方法創(chuàng)建線程對(duì)象 必須手動(dòng)開(kāi)啟線程 否則不會(huì)調(diào)用線程的執(zhí)行方法
NSThread * thread1 = [[NSThread alloc]initWithTarget:<#(nonnull id)#> selector:<#(nonnull SEL)#> object:<#(nullable id)#>]
//開(kāi)始線程
[thread start];
添加間隔時(shí)間
[NSThread sleepForTimeInterval:0.5];
立即停止
[NSThread exit];
NSThread * thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadMain1:) object:@(20)];
[thread1 start];
NSDictionary * dic = @{@"thread":thread1,@"da":@(100)};
NSThread * thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(threadMain2:) object:dic];
[thread2 start];
判斷當(dāng)前線程是否接收到cancel消息
[[NSThread currentThread]isCancelled]
向線程1發(fā)送結(jié)束通知
[dic[@"thread"] cancel];
//為通知中心添加觀察者 觀察線程執(zhí)行結(jié)束
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(threadExists:) name:NSThreadWillExitNotification object:nil];
//獲取 調(diào)用該方法的線程
NSThread * thread = [NSThread currentThread];
線程鎖
NSLock * lock;
初始化線程鎖
lock = [[NSLock alloc]init];
同一資源只能被一個(gè)應(yīng)用 讀/寫(xiě)
如果某資源被一個(gè)應(yīng)用使用 則為該資源上鎖 使用完釋放訪問(wèn)權(quán)限
2.GCD(Grand Central Dispatch)多線程優(yōu)化技術(shù)
任務(wù):同步執(zhí)行 異步執(zhí)行( 區(qū)別;是否開(kāi)啟新線程)
隊(duì)列:串行隊(duì)列 并行隊(duì)列
遵守FIFO(先進(jìn)先出)
主線程
dispatch_queue_t main = dispatch_get_main_queue();
//開(kāi)啟新線程
//串行
開(kāi)啟新線程
@param label#> 標(biāo)識(shí) 用于標(biāo)識(shí)唯一線程/隊(duì)列 description#>
@param attr#> 用于標(biāo)識(shí)當(dāng)前隊(duì)列是串行還是并行 description#>
DISPATCH_QUEUE_SERIAL 串行
DISPATCH_QUEUE_CONCURRENT 并行
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
//并行
方式一
dispatch_queue_t queue2 = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
任務(wù)(同步,異步)
同步
1.任務(wù)放到哪個(gè)隊(duì)列中
2.執(zhí)行事件
dispatch_sync(queue, ^{
NSLog(@"同步");
});
異步
dispatch_async(queue, ^{
NSLog(@"異步");
});
GCD組
dispatch_group_t group = dispatch_group_create();
創(chuàng)建隊(duì)列
@param identifier#> 線程優(yōu)先級(jí) description#>
@param flags#> 標(biāo)示符 description#>
dispatch_queue_t queue3 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
將線程queue放到group組中
dispatch_group_async(group, queue3, ^{
});
將隊(duì)列放到組中,當(dāng)所有隊(duì)列任務(wù)執(zhí)行完畢后可提供通知
dispatch_group_notify(group, queue3, ^{
});
3.(封裝gcd)
NSOperationQueue(隊(duì)列)
NSOperation(任務(wù))
創(chuàng)建任務(wù)(需要手動(dòng)開(kāi)啟)
NSInvocationOperation * oper = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(refresh) object:nil];
開(kāi)啟
[oper start];
創(chuàng)建方式2(推薦使用)
NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"");
}];
任務(wù)結(jié)束回調(diào)
[operation setCompletionBlock:^{
NSLog(@"");
}];
[operation start];
隊(duì)列
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
創(chuàng)建任務(wù)放到隊(duì)列中
NSBlockOperation * oper = [NSBlockOperation blockOperationWithBlock:^{
}];
任務(wù)加到隊(duì)列中即可開(kāi)啟
[queue addOperation:oper];
添加線程依賴(lài) operation 執(zhí)行完再執(zhí)行oper
[oper addDependency:operation];
UI刷新操作必須回主線程
1.回到主線程進(jìn)行刷新操作
2.參數(shù)
3.是否終止線程 NO
[self performSelectorOnMainThread:@selector(main) withObject:nil waitUntilDone:NO];
dispatch_async(dispatch_get_main_queue(), ^{
//刷新UI
});
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
// 刷新UI
}];
延時(shí)