GCD的几个简单的运用,之前对GCD感觉不是很熟悉,自己下来学习了一下,总结了几个情况,不好的地方多改进,直接上代码
首先要下载DCD文件夹,导入工程里面引入头文件
1 GCD的延时执行 主要运用了GCDQueue
//NSThread方式的延时执行操作,代码冗杂,精确度高可以取消延时执行操作
[selfperformSelector:@selector(threadEvent:)withObject:selfafterDelay:2.f];
//取消延时执行操作
[NSObjectcancelPreviousPerformRequestsWithTarget:self];
//GCD,不能取消当前的操作,执行简洁
[GCDQueueexecuteInMainQueue:^{
NSLog(@"GCD线程事件");
}afterDelaySecs:2.f];
2 线程组 监听执行情况,管理线程的运行情况
//初始化线程组合
GCDGroup * group = [[GCDGroupalloc]init];
//创建一个线程队列
GCDQueue * queue = [[GCDQueuealloc]initConcurrent];
//让线程在group中执行(线程1)
[queue execute:^{
sleep(1);
NSLog(@"线程1执行完毕");
} inGroup:group];
//让线程在group中执行(线程2)
[queue execute:^{
sleep(3);
NSLog(@"线程2执行完毕");
} inGroup:group];
//监听线程组是否执行结束,然后执行线程3
[queue notify:^{
NSLog(@"线程3执行完毕");
} inGroup:group];
3 GCD的定时器 与NSTimer比较,后者的时间精度更加的准确,主要是用在当前的runloop中,如果再tableview运行可能会出现很多奇怪的问题
//运行GCDTimer
[selfrunGCDTimer];
//运行NSTimer
[selfrunNstimer];
-(void)runGCDTimer{
//初始化定时器
self.gcdTimer = [[GCDTimeralloc]initInQueue:[GCDQueuemainQueue]];
//指定时间间隔以及要执行的时间
[self.gcdTimerevent:^{
NSLog(@"GCD线程事件");
} timeInterval:NSEC_PER_SEC];
//运行定时器
[self.gcdTimerstart];
}
-(void)runNstimer{
//初始化并激活定时器
self.nstimer = [NSTimerscheduledTimerWithTimeInterval:1target:selfselector:@selector(timerEvent)userInfo:nilrepeats:YES];
}
4 GCD的信号量可以将异步线程转换成同步线程,可以解决高清图片显示问题,画面卡顿等
//图片地址可以自己选择,我是随便找的一个地址
self.view1 = [selfcreatImageViewWithFrame:CGRectMake(0,0,100,100)];
self.view2 = [selfcreatImageViewWithFrame:CGRectMake(100,0,100,100)];
self.view3 = [selfcreatImageViewWithFrame:CGRectMake(200,0,100,100)];
NSString * net1 =@"http://pic.cnitblog.com/avatar/607542/20140226182241.png";
NSString * net2 =@"http://pic.cnitblog.com/avatar/708810/20141230105233.png";
NSString * net3 =@"http://pic.cnitblog.com/avatar/704178/20141216150843.png";
//初始化信号量
GCDSemaphore * semaphore =[[GCDSemaphorealloc]init];
//图片1
[GCDQueueexecuteInGlobalQueue:^{
UIImage * image1 = [selfaccessDataByNetString:net1];
[GCDQueueexecuteInGlobalQueue:^{
[UIViewanimateWithDuration:2.fanimations:^{
self.view1.image = image1;
self.view1.alpha =1.f;
} completion:^(BOOL finished) {
//发送信号
[semaphore signal];
}];
}];
}];
//图片2
[GCDQueueexecuteInGlobalQueue:^{
UIImage * image2 = [selfaccessDataByNetString:net2];
//阻塞
[semaphore wait];
[GCDQueueexecuteInGlobalQueue:^{
[UIViewanimateWithDuration:2.fanimations:^{
self.view2.image = image2;
self.view2.alpha =1.f;
} completion:^(BOOL finished) {
//发送信号
[semaphore signal];
}];
}];
}];
//图片3
[GCDQueueexecuteInGlobalQueue:^{
UIImage * image3 = [selfaccessDataByNetString:net3];
//阻塞
[semaphore wait];
[GCDQueueexecuteInGlobalQueue:^{
[UIViewanimateWithDuration:2.fanimations:^{
self.view3.image = image3;
self.view3.alpha =1.f;
} completion:^(BOOL finished) {
}];
}];
}];
//创建view
-(UIImageView*)creatImageViewWithFrame:(CGRect)frame{
UIImageView * imageview = [[UIImageViewalloc]initWithFrame:frame];
imageview.alpha =0.f;
[self.viewaddSubview:imageview];
return imageview;
}
//获取网络图片
-(UIImage*)accessDataByNetString:(NSString*)string{
NSURLRequest * request = [NSURLRequestrequestWithURL:[NSURLURLWithString:string]];
NSData * data = [NSURLConnectionsendSynchronousRequest:requestreturningResponse:nilerror:nil];
return [UIImageimageWithData:data];
}
5 同步执行+主队列(死锁)
|
- (
void
)asyncMain{
//获取主队列
dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@
"---start---"
);
//使用异步函数封装三个任务
dispatch_async(queue, ^{
NSLog(@
"任务1---%@"
, [NSThread currentThread])
});
dispatch_async(queue, ^{
NSLog(@
"任务2---%@"
, [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@
"任务3---%@"
, [NSThread currentThread]);
});
NSLog(@
"---end---"
);
}
打印结果:---start---
解释:
“任务1”和“打印end”两个任务互相等待,造成死锁
|
8
9
10
11
12
13
14
15
16
17
|
- (
void
)asyncMain{
//获取主队列
dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@
"---start---"
);
//使用异步函数封装三个任务
dispatch_async(queue, ^{
NSLog(@
"任务1---%@"
, [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@
"任务2---%@"
, [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@
"任务3---%@"
, [NSThread currentThread]);
});
NSLog(@
"---end---"
);
}
|