(1)GCD實(shí)現(xiàn)的同步異步项钮、串行并行。
——同步sync應(yīng)用場(chǎng)景:用戶登錄署隘,利用阻塞
——串行異步應(yīng)用場(chǎng)景:下載等耗時(shí)間的任務(wù)
/**
*? 因?yàn)槭钱惒窖窍叮蚤_(kāi)通了子線程,但是因?yàn)槭谴嘘?duì)列恃鞋,所以只需要開(kāi)通1個(gè)子線程(2)崖媚,它們?cè)谧泳€程中順序執(zhí)行亦歉。最常用。
-(void)gcdDemo1{
dispatch_queue_t q1=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_SERIAL);
for (int i=0; i<10; i++) {
dispatch_async(q1, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
}
*? 因?yàn)槭钱惒匠┭疲蚤_(kāi)通了子線程,且因?yàn)槭遣⑿嘘?duì)列荠呐,所以開(kāi)通了好多個(gè)子線程,具體幾個(gè)呵恢,無(wú)人知曉媚创,看運(yùn)氣。線程數(shù)量無(wú)法控制钞钙,且浪費(fèi)。
-(void)gcdDemo2{
dispatch_queue_t q2=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_CONCURRENT);
for (int i=0; i<10; i++) {
dispatch_async(q2, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
}
*? 因?yàn)槭峭教绷詿o(wú)論是并行隊(duì)列還是串行隊(duì)列本刽,都是在主線程中執(zhí)行
-(void)gcdDemo3{
dispatch_queue_t q1=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_SERIAL);
for (int i=0; i<10; i++) {
dispatch_sync(q1, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
}
*? 全局隊(duì)列和并行隊(duì)列類似(全局隊(duì)列不需要?jiǎng)?chuàng)建直接get即可,而導(dǎo)致其沒(méi)有名字暗挑,不利于后續(xù)調(diào)試)
-(void)gcdDemo5{
dispatch_queue_t q=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (int i=0; i<10; i++) {
dispatch_sync(q, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
for (int i=0; i<10; i++) {
dispatch_async(q, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
}
*? 因?yàn)槭侵骶€程别瞭,所以異步任務(wù)也會(huì)在主線程上運(yùn)行(1)。而如果是同步任務(wù)蝙寨,則阻塞了嗤瞎,因?yàn)橹骶€程一直會(huì)在運(yùn)行,所以后米的任務(wù)永遠(yuǎn)不會(huì)被執(zhí)行虹菲。
*? 主要用處掉瞳,是更新UI浪漠,更新UI一律在主線程上實(shí)現(xiàn)
-(void)gcdDemo6{
dispatch_queue_t q=dispatch_get_main_queue();
for (int i=0; i<10; i++) {
dispatch_sync(q, ^{
NSLog(@"%@",[NSThread currentThread]);
});
}
// for (int i=0; i<10; i++) {
// dispatch_async(q, ^{
// NSLog(@"%@",[NSThread currentThread]);
// });
// }
}
(2)NSOperation和NSOperationQueue實(shí)現(xiàn)的線程管理
/*
*? 1霎褐、只要是自己創(chuàng)建的隊(duì)列,添加進(jìn)來(lái)的操作(此處是block操作)冻璃,都在子線程上(2)
*? 2、只要是在主隊(duì)列中娘纷,添加進(jìn)來(lái)的操作跋炕,都在主線程上(1)
*? 兩個(gè)隊(duì)列不能同時(shí)搶一個(gè)任務(wù)操作
*/
-(void)opDemo1{
NSOperationQueue *queue=[[NSOperationQueue alloc]init];
NSBlockOperation *b=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@"%@",[NSThread currentThread]);
}];
[queue addOperation:b];
[[NSOperationQueue mainQueue]addOperation:b];
}
/**
*? 同上
*/
-(void)opDemo2{
NSInvocationOperation *i=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(helloWorld) object:nil];
NSOperationQueue *queue=[[NSOperationQueue alloc]init];
[queue addOperation:i];
[[NSOperationQueue mainQueue]addOperation:i];
}
-(void)helloWorld{
NSLog(@"hello,world!");
}
/**
*? 依賴關(guān)系:(1)可以保證執(zhí)行順序,也使得開(kāi)的子線程不會(huì)太多嬉探;(2)可以跨隊(duì)列棉圈,而串行是不可以跨隊(duì)列的,如最后更新UI則變成在主隊(duì)列中分瘾。
*? 這是NSOperation(NSBlockOperation和NSInvocationOperation)和NSOperationQueue的優(yōu)勢(shì)
*/
-(void)opDemo3{
NSBlockOperation *op1=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下載圖片 %@",[NSThread currentThread]);
}];
NSBlockOperation *op2=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@"修飾圖片 %@",[NSThread currentThread]);
}];
NSBlockOperation *op3=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@"保存圖片 %@",[NSThread currentThread]);
}];
NSBlockOperation *op4=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@"更新UI %@",[NSThread currentThread]);
}];
[op4 addDependency:op3];
[op3 addDependency:op2];
[op2 addDependency:op1];
NSOperationQueue *queue=[[NSOperationQueue alloc]init];
//設(shè)置同一時(shí)刻最大開(kāi)啟的線程數(shù)德召,這是NSOperationQueue特有的
[queue setMaxConcurrentOperationCount:2];
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
[[NSOperationQueue mainQueue]addOperation:op4];
}
(3)單例的實(shí)現(xiàn)(手寫單例要求)dispatch_once運(yùn)用,即重寫類的allocWithZone方法
@implementation WPObject
+(instancetype)allocWithZone:(struct _NSZone *)zone{
static WPObject *insta;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
insta=[super allocWithZone:zone];
});
return insta;
}
end