(1)GCD實現的同步異步、串行并行。
——同步sync應用場景:用戶登錄,利用阻塞
——串行異步應用場景:下載等耗時間的任務
/**
*? 因為是異步,所以開通了子線程,但是因為是串行隊列,所以只需要開通1個子線程(2),它們在子線程中順序執行。最常用。
-(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]);
});
}
}
*? 因為是異步,所以開通了子線程,且因為是并行隊列,所以開通了好多個子線程,具體幾個,無人知曉,看運氣。線程數量無法控制,且浪費。
-(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]);
});
}
}
*? 因為是同步,所以無論是并行隊列還是串行隊列,都是在主線程中執行
-(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]);
});
}
}
*? 全局隊列和并行隊列類似(全局隊列不需要創建直接get即可,而導致其沒有名字,不利于后續調試)
-(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]);
});
}
}
*? 因為是主線程,所以異步任務也會在主線程上運行(1)。而如果是同步任務,則阻塞了,因為主線程一直會在運行,所以后米的任務永遠不會被執行。
*? 主要用處,是更新UI,更新UI一律在主線程上實現
-(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實現的線程管理
/*
*? 1、只要是自己創建的隊列,添加進來的操作(此處是block操作),都在子線程上(2)
*? 2、只要是在主隊列中,添加進來的操作,都在主線程上(1)
*? 兩個隊列不能同時搶一個任務操作
*/
-(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!");
}
/**
*? 依賴關系:(1)可以保證執行順序,也使得開的子線程不會太多;(2)可以跨隊列,而串行是不可以跨隊列的,如最后更新UI則變成在主隊列中。
*? 這是NSOperation(NSBlockOperation和NSInvocationOperation)和NSOperationQueue的優勢
*/
-(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];
//設置同一時刻最大開啟的線程數,這是NSOperationQueue特有的
[queue setMaxConcurrentOperationCount:2];
[queue addOperation:op1];
[queue addOperation:op2];
[queue addOperation:op3];
[[NSOperationQueue mainQueue]addOperation:op4];
}
(3)單例的實現(手寫單例要求)dispatch_once運用,即重寫類的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