1.iOS的三種多線程技術
1.NSThread每個NSThread對象對應一個線程梅屉,量級較輕(真正的多線程)
2.以下兩點是蘋果專門開發(fā)的“并發(fā)”技術皆愉,使得程序員可以不再去關心線程的具體使用問題蝉绷,更多利用POSIX
(1)NSOperation/NSOperationQueue面向對象的線程技術
(2)GCD —— Grand Central Dispatch(中央派發(fā)) 是基于C語言的框架(可能是pthread)徽职,可以充分利用多核叫倍,是蘋果推薦使用的多線程技術
以上這三種編程方式從上到下偷卧,抽象度層次是從低到高的,抽象度越高的使用越簡單吆倦,也是Apple最推薦使用的听诸,在項目中很多框架技術分別使用了不同多線程技術。
2.三種多線程技術的對比
?NSThread:
–優(yōu)點:NSThread 比其他兩個輕量級蚕泽,使用簡單
–缺點:需要自己管理線程的生命周期晌梨、線程同步、加鎖须妻、睡眠以及喚醒等仔蝌。線程同步對數(shù)據(jù)的加鎖會有一定的系統(tǒng)開銷
?NSOperation:
–不需要關心線程管理,數(shù)據(jù)同步的事情荒吏,可以把精力放在自己需要執(zhí)行的操作上
–NSOperation是面向對象的
?GCD:
–Grand Central Dispatch是由蘋果開發(fā)的一個多核編程的解決方案敛惊。iOS4.0+才能使用,是替代NSThread绰更, NSOperation的高效和強大的技術
–GCD是基于C語言的
3.三種多線程技術的實現(xiàn)
3.1. NSThread的多線程技術瞧挤,
1> 類方法直接開啟后臺線程锡宋,并執(zhí)行選擇器方法
detachNewThreadSelector
//?新建一個線程,調用@selector方法2 ?[NSThread?detachNewThreadSelector:@selector(bigDemo)?toTarget:self?withObject:nil];
2> 成員方法特恬,在實例化線程對象之后员辩,需要使用start執(zhí)行選擇器方法
initWithTarget
//?成員方法
NSThread?*thread?=?[[NSThread?alloc]?initWithTarget:self?selector:@selector(bigDemo)?object:nil];
//?啟動start線程
[thread?start];
對于NSThread的簡單使用,可以用NSObject的performSelectorInBackground替代
//?performSelectorInBackground是將bigDemo的任務放在后臺線程中執(zhí)行 [self?performSelectorInBackground:@selector(bigDemo)?withObject:nil];
同時鸵鸥,在NSThread調用的方法中,同樣要使用autoreleasepool進行內(nèi)存管理丹皱,否則容易出現(xiàn)內(nèi)存泄露妒穴。
//?自動釋放池?
//?負責其他線程上的內(nèi)存管理,在使用NSThread或者NSObject的線程方法時摊崭,一定要使用自動釋放池?
//?否則容易出現(xiàn)內(nèi)存泄露讼油。?
@autoreleasepool?{ }
3.2 NSOperation,面向對象的多線程技術
1> 使用步驟:
1) 實例化操作
//?實例化操作隊列
?_queue?=?[[NSOperationQueue?alloc]?init];
a) NSInvocationOperation
NSInvocationOperation?*op1?=?[[NSInvocationOperation?alloc]?initWithTarget:self?selector:@selector(opAction)?object:nil];
//?如果使用start呢簸,會在當前線程啟動操作
//????
[op1?start];
//?1.?一旦將操作添加到操作隊列矮台,操作就會啟動
[_queue?addOperation:op1];
b) NSBlockOperation
#pragma?mark?模仿下載網(wǎng)絡圖像?
-?(IBAction)operationDemo:(id)sender ?{?
//?1.?下載
NSBlockOperation?*op1?=?[NSBlockOperation?blockOperationWithBlock:^{?
NSLog(@"下載?%@"?,?[NSThread?currentThread]);?
}];
//?2.?濾鏡
NSBlockOperation?*op2?=?[NSBlockOperation?blockOperationWithBlock:^{
NSLog(@"濾鏡?%@"?,?[NSThread?currentThread]);
}];
//?3.?顯示
NSBlockOperation?*op3?=?[NSBlockOperation?blockOperationWithBlock:^{
?????????NSLog(@"更新UI?%@"?,?[NSThread?currentThread]);
?????}];
//?添加操作之間的依賴關系,所謂“依賴”關系根时,就是等待前一個任務完成后瘦赫,后一個任務才能啟動
//?依賴關系可以跨線程隊列實現(xiàn)
//?提示:在指定依賴關系時,注意不要循環(huán)依賴蛤迎,否則不工作确虱。
[op2?addDependency:op1];
[op3?addDependency:op2];
[op1?addDependency:op3];
[_queue?addOperation:op1];
[_queue?addOperation:op2];
[[NSOperationQueue?mainQueue]?addOperation:op3];
}
2) 將操作添加到隊列NSOperationQueue即可啟動多線程執(zhí)行
?[_queue?addOperation:op1];
?[_queue?addOperation:op2];
2> 更新UI使用主線程隊列
//兩方式
[NSOpeationQueue?mainQueue]?addOperation?^{
};
[[NSOperationQueue?mainQueue]?addOperation:op3];
3> 操作隊列的setMaxConcurrentOperationCount
可以設置同時并發(fā)的線程數(shù)量!
//?控制同時最大并發(fā)的線程數(shù)量
[_queue?setMaxConcurrentOperationCount:2];
提示:此功能僅有NSOperation有替裆!
4> 使用addDependency可以設置任務的執(zhí)行先后順序校辩,同時可以跨操作隊列指定依賴關系
//?添加操作之間的依賴關系,所謂“依賴”關系辆童,就是等待前一個任務完成后宜咒,后一個任務才能啟動
//?依賴關系可以跨線程隊列實現(xiàn)
//?提示:在指定依賴關系時,注意不要循環(huán)依賴把鉴,否則不工作故黑。
[op2?addDependency:op1];
[op3?addDependency:op2];
[op1?addDependency:op3];
提示:在指定依賴關系時,注意不要循環(huán)依賴纸镊,否則不工作倍阐。
3.3. GCD,C語言
GCD就是為了在“多核”上使用多線程技術
1> 要使用GCD逗威,所有的方法都是dispatch開頭的
2> 名詞解釋
global全局
queue隊列
async異步
sync同步
3> 要執(zhí)行異步的任務峰搪,就在全局隊列中執(zhí)行即可
dispatch_async 異步執(zhí)行控制不住先后順序
4> 關于GCD的隊列
全局隊列dispatch_get_global_queue
參數(shù):優(yōu)先級 DISPATCH_QUEUE_PRIORITY_DEFAULT
始終是 0
dispatch_queue_t?queue?=?dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,?0);
可同步 可異步
串行隊列
dispatch_queue_t?queue?=?dispatch_queue_create("myQueue",?DISPATCH_QUEUE_SERIAL);
是創(chuàng)建得到的,不能直接獲取
只能同步
主隊列dispatch_get_main_queue
dispatch_async(dispatch_get_main_queue(),?^{
? ? ? ? ?NSLog(@"main?-?>?%@",?[NSThread?currentThread]);
});
只能同歩
5> 異步和同步與方法名無關凯旭,與運行所在的隊列有關概耻!
同步主要用來控制方法的被調用的順序