iOS开发之多线程
2016-03-31 18:32
381 查看
iOS中多线程的实现方式有NSThread、NSOperation和GCD(全称:Grand
Central Dispatch)。
1.NSThread:
优点:NSThread 比其他两个轻量级
缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销
有两种初始化方式
第一种先创建线程对象,然后再运行线程操作,在运行线程操作前可以设置线程的优先级等线程信息
//NSThread * thread= [[NSThread alloc]initWithTarget:selfselector:@selector(calculate) object:nil];
//// 开启子线程
//[threadstart];
第二种直接创建线程并且开始运行线程
[NSThread detachNewThreadSelector:@selector(calculate)toTarget:selfwithObject:nil];
在子线程中执行
-(void)calculate
{
// 在子线程里面执行的事件创建对象时可能会用到便利构造器,这时占用的内存释放不掉,所以和主线程一样在外面加一个自动释放池
@autoreleasepool {
NSBlockOperation *operation = [NSBlockOperationblockOperationWithBlock:^{
NSLog(@"%d",[NSThreadisMainThread]);
}];
[operation start];
int a=0;
for(int i
=1; i <= 355;i
++){
[selfperformSelectorOnMainThread:@selector(test:)withObject:[NSStringstringWithFormat:@"%d",a]waitUntilDone:YES];
a +=i;
}
}
}
2.NSOperation
使用 NSOperation的方式有两种,
一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。
另一种是继承NSOperation
NSOperation就和java.lang.Runnable接口很相似。和Java的Runnable一样,NSOperation也是设计用来扩展的,只需继承重写NSOperation的一个方法main。相当与java 中Runnalbe的Run方法。然后把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它。
NSBlockOperation初始化方式
NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
// NSLog(@"该吃饭了(⊙o⊙)哦");
//}];
//
//[queue addOperation:block];
最大并发数.所谓的最大并发数指的是同时执行的任务个数。如果最大并发数设置为1,可以实现多线程下的线程同步
// queue.maxConcurrentOperationCount = 1;
3.GCD
GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行。
dispatch queue分为下面三种:
Serial
又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。
Concurrent
又称为global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。
Main dispatch queue
它是全局可用的serial queue,它是在应用程序主线程上执行任务的。
下面来看gcd的使用
//
串行队列
dispatch_queue_t myQueue =dispatch_queue_create("com.baidu.myQueue",DISPATCH_QUEUE_SERIAL);
dispatch_async(myQueue, ^{
NSLog(@"%d",[NSThreadisMainThread]);
});//全局队列
dispatch_queue_t global
=dispatch_get_global_queue(0,0);
dispatch_async(global, ^{
NSLog(@"%d,dddd",[NSThreadisMainThread]);
});
1.为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面。
2、dispatch_group_async的使用
dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。
3、dispatch_barrier_async的使用
4、dispatch_after
// 延迟多少秒之后执行任务
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(3*NSEC_PER_SEC)),dispatch_get_main_queue(),
^{
NSLog(@"0000");
});
5、dispatch_once
只执行一次,单例的创建可以使用这个方法
static dispatch_once_tonceToken;
dispatch_once(&onceToken, ^{
NSLog(@"1111");
});
6、 dispatch_apply
执行多次
NSArray * array=@[@1,@2,@3];
dispatch_apply(array.count,dispatch_get_global_queue(0,0),
^(size_t i){
NSLog(@"%zu%@",i,array[i]);
});
Central Dispatch)。
1.NSThread:
优点:NSThread 比其他两个轻量级
缺点:需要自己管理线程的生命周期,线程同步。线程同步对数据的加锁会有一定的系统开销
有两种初始化方式
第一种先创建线程对象,然后再运行线程操作,在运行线程操作前可以设置线程的优先级等线程信息
//NSThread * thread= [[NSThread alloc]initWithTarget:selfselector:@selector(calculate) object:nil];
//// 开启子线程
//[threadstart];
第二种直接创建线程并且开始运行线程
[NSThread detachNewThreadSelector:@selector(calculate)toTarget:selfwithObject:nil];
在子线程中执行
-(void)calculate
{
// 在子线程里面执行的事件创建对象时可能会用到便利构造器,这时占用的内存释放不掉,所以和主线程一样在外面加一个自动释放池
@autoreleasepool {
NSBlockOperation *operation = [NSBlockOperationblockOperationWithBlock:^{
NSLog(@"%d",[NSThreadisMainThread]);
}];
[operation start];
int a=0;
for(int i
=1; i <= 355;i
++){
[selfperformSelectorOnMainThread:@selector(test:)withObject:[NSStringstringWithFormat:@"%d",a]waitUntilDone:YES];
a +=i;
}
}
}
2.NSOperation
使用 NSOperation的方式有两种,
一种是用定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。
另一种是继承NSOperation
NSOperation就和java.lang.Runnable接口很相似。和Java的Runnable一样,NSOperation也是设计用来扩展的,只需继承重写NSOperation的一个方法main。相当与java 中Runnalbe的Run方法。然后把NSOperation子类的对象放入NSOperationQueue队列中,该队列就会启动并开始处理它。
NSBlockOperation初始化方式
NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
// NSLog(@"该吃饭了(⊙o⊙)哦");
//}];
//
//[queue addOperation:block];
最大并发数.所谓的最大并发数指的是同时执行的任务个数。如果最大并发数设置为1,可以实现多线程下的线程同步
// queue.maxConcurrentOperationCount = 1;
3.GCD
GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行。
dispatch queue分为下面三种:
Serial
又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。
Concurrent
又称为global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。
Main dispatch queue
它是全局可用的serial queue,它是在应用程序主线程上执行任务的。
下面来看gcd的使用
//
串行队列
dispatch_queue_t myQueue =dispatch_queue_create("com.baidu.myQueue",DISPATCH_QUEUE_SERIAL);
dispatch_async(myQueue, ^{
NSLog(@"%d",[NSThreadisMainThread]);
});//全局队列
dispatch_queue_t global
=dispatch_get_global_queue(0,0);
dispatch_async(global, ^{
NSLog(@"%d,dddd",[NSThreadisMainThread]);
});
1.为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 耗时的操作
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面
});
});
2、dispatch_group_async的使用
dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"group1");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"group2");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"group3");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"updateUi");
});
3、dispatch_barrier_async的使用
dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行
dispatch_queue_t queue = dispatch_queue_create("com.baidu.myQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"1");
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:4];
NSLog(@"2");
});
dispatch_barrier_async(queue, ^{
NSLog(@"**");
[NSThread sleepForTimeInterval:4];
});
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"3");
});
4、dispatch_after
// 延迟多少秒之后执行任务
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(3*NSEC_PER_SEC)),dispatch_get_main_queue(),
^{
NSLog(@"0000");
});
5、dispatch_once
只执行一次,单例的创建可以使用这个方法
static dispatch_once_tonceToken;
dispatch_once(&onceToken, ^{
NSLog(@"1111");
});
6、 dispatch_apply
执行多次
NSArray * array=@[@1,@2,@3];
dispatch_apply(array.count,dispatch_get_global_queue(0,0),
^(size_t i){
NSLog(@"%zu%@",i,array[i]);
});
相关文章推荐
- iOS 货币计算
- iOS 2.0 版本切入点
- 公司用到的一些 iOS 开源库和第三方组件
- 玩转iOS开发 - 多线程开发
- iOS 自定义TabBar(仿新浪微博TabBar)
- IOS 获取当前版本信息
- ios保存录制好的视频到相簿的方法
- iOS开发调试技巧总结
- iOS端应用统计SDK开发简介
- iOS开发之.pch在工程出现移动的情况下出现not found 的情况
- iOS开发之视频播放时出现播放不了的情况
- iOS学习笔记10-- & 与 *
- nagios详解
- 有关ios过度动画CATransition的一些特效
- iOS开发之linker command failed with exit code 1 (use -v to see invocation)
- iOS开发实践教程(二)之真机调试流程
- iOS开发 上架流程、真机调试、证书、配置文件
- iOS学习笔记09--const、宏、static、extern
- IOS开发之——手动设置屏幕旋转
- iOS获取通讯录联系人信息