在iOS中多线程一直是不可或缺的一部分,下面就说几种多线程的使用,下面介绍一种多线程使用的经典场景
首先我们介绍NSThread
创建线程
_thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
_thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
_thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
我们让线程去对数据进行操作
设置一个数值为20
出于线程安全的考虑,我们锁住当前线程并使其等待一些时间
-(void)run{
while (true) {
//锁住当前线程对象,其他线程等待
@synchronized(self) {
if (_count > 0) {
//使线程休眠一段时间(进行计算)
[NSThread sleepForTimeInterval:0.00003];
_count --;
NSLog(@" ==== %@操作后的结果为%d",[NSThread currentThread].name,_count);
}else{
//退出线程
NSLog(@"xiancheng ==== %@",[NSThread currentThread].name);
[NSThread exit];//退出线程,但是线程仍为开启状态
}
}
}
}
出现的打印结果如下
2016-06-02 19:44:22.209 ThreadSafeDemo[768:36946] ==== 第一个窗口操作后的结果为19
2016-06-02 19:44:22.210 ThreadSafeDemo[768:36947] ==== 第二个窗口操作后的结果为18
2016-06-02 19:44:22.211 ThreadSafeDemo[768:36948] ==== 第三个窗口操作后的结果为17
2016-06-02 19:44:22.212 ThreadSafeDemo[768:36946] ==== 第一个窗口操作后的结果为16
下面我们用GCD实现图片加载
分别采用串行队列、并行队列,和组队列的加载方式
串行队列
dispatch_queue_t queueT = dispatch_queue_create("com.down", DISPATCH_QUEUE_SERIAL);
__weak ViewController *weakSelf = self;//防止循环引用
dispatch_async(queueT, ^{//执行异步线程下载图片
UIImage *img = [weakSelf downLoadIMG:@"http://image.fvideo.cn/uploadfile/2012/03/15/20120315110710016.jpg"];
dispatch_async(dispatch_get_main_queue(), ^{//通知主线程,更新
_imgView2.image = img;
});
});
__weak ViewController *weakSelf2 = self;//防止循环引用
dispatch_async(queueT, ^{
UIImage *img = [weakSelf2 downLoadIMG:@"http://imagefiles.dfhon.com/imagefiles/2010/20101102/151049%20%281%29.jpg"];
dispatch_async(dispatch_get_main_queue(), ^{//通知主线程,更新
_imgView3.image = img;
});
});
会很明显的发现一个加载的先后顺序
并行队列
//创建并行对象
dispatch_queue_t queueT = dispatch_queue_create("com.down", DISPATCH_QUEUE_CONCURRENT);
__weak ViewController *weakSelf = self;//防止循环引用
dispatch_async(queueT, ^{//执行异步线程下载图片
UIImage *img = [weakSelf downLoadIMG:@"http://image.fvideo.cn/uploadfile/2012/03/15/20120315110710016.jpg"];
dispatch_async(dispatch_get_main_queue(), ^{//通知主线程,更新
_imgView2.image = img;
});
});
__weak ViewController *weakSelf2 = self;//防止循环引用
dispatch_async(queueT, ^{
UIImage *img = [weakSelf2 downLoadIMG:@"http://imagefiles.dfhon.com/imagefiles/2010/20101102/151049%20%281%29.jpg"];
dispatch_async(dispatch_get_main_queue(), ^{//通知主线程,更新
_imgView3.image = img;
});
});
这样下载也会出现一个先后出现的问题,但是先后出现的顺序是随机的,那么怎么样才能同时加载呢
组队列
//创建组
dispatch_group_t group = dispatch_group_create();
//组队列
dispatch_queue_t groupT = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
__block UIImage *img1 = nil;
__weak ViewController *weakSelf = self;//防止循环引用
dispatch_group_async(group, groupT, ^{
img1 = [weakSelf downLoadIMG:@"http://imagefiles.dfhon.com/imagefiles/2010/20101102/151049%20%281%29.jpg"];
});
__block UIImage *img2 = nil;
__weak ViewController *weakSelf2 = self;//防止循环引用
dispatch_group_async(group, groupT, ^{
img2 = [weakSelf2 downLoadIMG:@"http://image.fvideo.cn/uploadfile/2012/03/15/20120315110710016.jpg"];
});
//在下载完成之后通知主队列加载图片
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
_imgView2.image = img1;
_imgView3.image = img2;
});
-(UIImage *)downLoadIMG:(NSString *)url{//图片的下载方法
NSURL *urlAA = [NSURL URLWithString:url];
NSData *data = [NSData dataWithContentsOfURL:urlAA];
NSLog(@"data == %@",data);
UIImage *img = [UIImage imageWithData:data];
return img;
}