iOS中的多线程及GCD
多线程中的一些概念
//任务:代码段 方法 线程就是执行这些任务
//NSThread类 创建线程 执行线程
[NSThread isMainThread]//判断是否是主线程
#import "AppDelegate.h" @implementation AppDelegate
-(void)dealloc
{
[_window release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor]; //实现多线程
//任务:代码段 方法 线程就是执行这些任务
//NSThread类 创建线程 执行线程
NSLog(@"-------------%d",[NSThread isMainThread]);//判断是否是主线程 //实现多线程的方式一
//使用 根类 NSObject 中的 performSelectorxxx方法
//UI的刷新一定要在主线程里进行 子线程刷新UI会异常 刷新不了 或者延迟刷新.
// [self performSelectorInBackground:@selector(aa) withObject:nil]; //实现多线程的方式二
//使用 NSThread 类(多线程类)
//创建一个线程 ,并让线程执行 self 的aa方法 //线程分两种 脱离线程 和 非脱离线程
//脱离线程;执行玩任务之后,自动销毁的线程
//非脱离线程 : 执行完任务之后 ,不会被销毁的线程,可以后续执行别的任务
//每一个线程都自带一个NSRunLoop对象,runloop默认是关闭的.一旦runloop开启,你的线程就会成为非脱离线程.runloop帮你轮询有没有新的任务分配到了这个线程里面 //[NSThread detachNewThreadSelector:@selector(aa) toTarget:self withObject:nil]; //创建一个线程,线程需要执行的任务是self 的aa 方法
// NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(aa) object:nil];
// [thread start];//开始执行线程 解决了延迟执行的问题 在想执行的时候执行 //第三种实现多线程的方式NSOperationQueue
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(aa) object:nil];
// [op1 start]; NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"这是一个block operation");
}];
//线程同步就是串行 线程之间有依赖关系的时候使用同步 实现同步就把NSOperationQueue的MaxConcurrentOperationCount最大并发数为1
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// NSLog(@"~~~~~~~~~~~~~~~~~~~~~~~~%d",queue.maxConcurrentOperationCount);
[queue setMaxConcurrentOperationCount:];//设置最大并发数为1
[queue addOperation:op1];//只需要把操作放到队列里即可,不需要人为调用start,queue会根据op的排队情况,帮你调用start .会智能帮为op安排线程
[queue addOperation:op2]; [self.window makeKeyAndVisible];
return YES;
} - (void)aa
{
//如果在子线程中执行任务 我们需要在任务里面加一个自动释放池
//因为.线程与线程之间是相互独立的,但是资源是共享的,共享堆 空间 ,如果一个线程开辟了空间 没有释放 其他线程也无法 使用这块已经开辟的空间
//尤其是当子线程里 大量使用便利构造器的时候 会导致很多堆空间无法回收内存
//线程共享堆 ,栈不共享 每个子线程默认以栈的大小是512k 主线程栈大小事1M 栈主要是放 局部变量的,局部变量出了方法就会被销毁,因此,尽管只有512k或着1M但是已经够用的了 ,,栈空间的大小必须是4k的整数倍
//
@autoreleasepool {
for (int i = ; i<; i++) {
NSLog(@"%d",i);
}
NSLog(@"#################%d",[NSThread isMainThread]); [self performSelectorOnMainThread:@selector(bb) withObject:nil waitUntilDone:YES];
NSLog(@"子线程结束了");
} }
- (void)bb
{
@autoreleasepool {
NSLog(@"??????????????????????%d",[NSThread isMainThread]);
for (int i = ; i<; i++) {
NSLog(@"-%d",i);
}
NSLog(@"刷新你的UI");
} }
//GCD中的几个概念
1.Queue 队列 dispatch Queue(分发队列) 若干个task
2.Task 任务 (单独的方法或者代码段 block)
3.Thread 线程
GCD全程 Grand Central Dispatch
Task是一个个单独的任务(函数. 方法 . block)
Queue 里存放的是一个或者多个Task
Thread ,为了保证Task能顺利执行,Queue会开辟适当的Thread,在开辟的Thread里面执行Task
Queue分两种
一.serialQueue(串行队列)
特点:任务先进先出 ,排在前面的任务先执行,执行完之后,后面的任务才开始执行,即:任务1先执行,任务1执行完之后,任务2开始执行,任务2执行完之后,任务3开始执行,任务3执行完之后,任务4......
二.concurrentQueue(并发队列)
特点:任务先进先出,排载前面的任务先开始执行,一旦开始,后面的任务就开始执行(无需等前一个任务执行完毕).即:任务1先开始执行,无需等待任务1执行完,任务2就开始执行,无需等待任务2执行完,任务3就开始执行.无需等待任务3.......
你把任务放到什么样的队列里,任务就会遵守这个队列的规则
- (IBAction)method1:(id)sender {
//如果想让任务串行,我们需要使用serialQueue
//我们有2种途径获取serialQueue
//方法1.使用系统自带的mainQueue(单例)
//mainQueue智慧为任务(无论多少个任务)开辟一个线程,而且这个线程是主线程
//思考: 这些任务 在主线程里面执行, 不会还会卡死主线程吗? 为什么系统还要给你提供mainQueue?
// dispatch_queue_t queue = dispatch_get_main_queue();
//
// dispatch_async(queue, ^{
// NSLog(@"任务1 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// });
// dispatch_async(queue, ^{
// NSLog(@"任务2 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// });
// dispatch_async(queue, ^{
// NSLog(@"任务3 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// });
// dispatch_async(queue, ^{
// NSLog(@"任务4 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// });
// dispatch_async(queue, ^{
// NSLog(@"任务5 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// }); //方法2.自己创建一个serialQueue
//自己创建的serialQueue也只为任务(无论多少个任务)开辟一个线程,这些线程是在子线程里执行的,既不会卡死主线程,也能实现线程同步
//GCD中函数带create 要用release释放
// dispatch_queue_t queue = dispatch_queue_create("com.limice.mySerialQueue", DISPATCH_QUEUE_SERIAL);
// dispatch_async(queue, ^{
// NSLog(@"任务1 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// });
// dispatch_async(queue, ^{
// NSLog(@"任务2 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// });
// dispatch_async(queue, ^{
// NSLog(@"任务3 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// });
// dispatch_async(queue, ^{
// NSLog(@"任务4 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// });
// dispatch_async(queue, ^{
// NSLog(@"任务5 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
// });
//释放GCD中所有通过create创建的对象
// dispatch_release(queue);
}
- (IBAction)method2:(id)sender {
//如果想并发执行任务,我们使用concurrentQueue.
//获得concurrentQueue的途径仍然有两种
//第一种:使用系统自带的globalQueue(单例)
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //第二种:使用自己创建的concurrentQueue
dispatch_queue_t queue = dispatch_queue_create("com.limice.myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"任务1 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_async(mainQueue, ^{
NSLog(@"刷新你的UI");
});
});
dispatch_async(queue, ^{
NSLog(@"任务2 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务3 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务4 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务5 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
});
dispatch_release(queue);
}
- (IBAction)method3:(id)sender {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
//延迟执行(3s)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)( * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"");
}); }
- (IBAction)method4:(id)sender {
NSArray *arr = @[@"红楼梦",@"水浒传",@"西游记",@"三国演义",@"封神演义"]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
//重复执行一个任务
dispatch_apply(, queue, ^(size_t t) {
NSLog(@"%@",arr[t]);
});
}
- (IBAction)method5:(id)sender {
//给任务分组
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); dispatch_group_async(group, queue, ^{
NSLog(@"任务1");
});
dispatch_group_async(group, queue, ^{
NSLog(@"任务2");
}); dispatch_group_async(group, queue, ^{
NSLog(@"任务3");
});
dispatch_group_async(group, queue, ^{
NSLog(@"任务4");
});
dispatch_group_async(group, queue, ^{
NSLog(@"任务5"); });
dispatch_group_async(group, queue, ^{
NSLog(@"任务6");
});
dispatch_async(queue, ^{
NSLog(@"任务4 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任务5 是否是主线程: %d %@",[NSThread isMainThread],[NSThread currentThread]);
});
dispatch_group_notify(group, queue, ^{
NSLog(@"走,出发");
});
}
- (IBAction)method6:(id)sender {
dispatch_queue_t queue = dispatch_queue_create("com.limice.myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"所有男同学同学,是否主线程 %d %@",[NSThread isMainThread],[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"年龄20岁以上的同学,是否主线程 %d %@",[NSThread isMainThread],[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"河南的同学,是否主线程 %d %@",[NSThread isMainThread],[NSThread currentThread]);
});
dispatch_barrier_async(queue,^{
NSLog(@"写入");
});
dispatch_async(queue, ^{
NSLog(@"月薪上万的同学,是否主线程 %d %@",[NSThread isMainThread],[NSThread currentThread]);
}); }
- (IBAction)method7:(id)sender {
//用来写单例
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"hello");
});
}
- (IBAction)method8:(id)sender {
dispatch_queue_t queue = dispatch_queue_create("com.limice.myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
//同步(串行):必须等block执行完,才执行后面的语句
//异步就是并行
dispatch_sync(queue, ^{
for (int i = ; i<; i++) {
NSLog(@"%d",i);
}
});
NSLog(@"over");
}
- (IBAction)method9:(id)sender {
dispatch_queue_t queue = dispatch_queue_create("com.limice.myConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async_f(queue, @"hello world", aa);
}
void aa(void *context)
{
NSLog(@"%@",context);
}
iOS中的多线程及GCD的更多相关文章
- OS X 和iOS 中的多线程技术(上)
OS X 和iOS 中的多线程技术(上) 本文梳理了OS X 和iOS 系统中提供的多线程技术.并且对这些技术的使用给出了一些实用的建议. 多线程的目的:通过并发执行提高 CPU 的使用效率,进而提供 ...
- OS X 和iOS 中的多线程技术(下)
OS X 和iOS 中的多线程技术(下) 上篇文章中介绍了 pthread 和 NSThread 两种多线程的方式,本文将继续介绍 GCD 和 NSOperation 这两种方式.. 1.GCD 1. ...
- iOS中的多线程 NSOperation
在ios中,使用多线程有三种方式,分别是:NSThread.NSOperation和NSOperationQueue.GCD,在本节,主要讲解一下NSOperation的使用. NSOperation ...
- IOS中的多线程和NSRunLoop概述(转载)
线程概述 有些程序是一条直线,从起点到终点,如Hello World,运行打印完,它的生命周期便结束了:有些程序是一个圆,不断循环,直到将它切断,如操作系统,一直运行直到你关机. 一个运行着的程序就 ...
- iOS中实现多线程的技术方案
pthread 实现多线程操作 代码实现: void * run(void *param) { for (NSInteger i = 0; i < 1000; i++) { ...
- iOS中的多线程基础
NSThread NSThread是一个苹果封装过的,面向对象的线程对象.但是它的生命周期需要我们自己来手动管理,所以使用不是很常见,比如[NSThread currentThread],它可以获取当 ...
- iOS中的多线程NSThread/GCD/NSOperation & NSOperationQueue
iOS多线程有四套多线程方案: Pthreads NSThread GCD NSOperation & NSOperationQueue 接下来我来一个一个介绍他们 Pthreads 在类Un ...
- iOS开发之多线程技术——GCD篇
本篇将从四个方面对iOS开发中GCD的使用进行详尽的讲解: 一.什么是GCD 二.我们为什么要用GCD技术 三.在实际开发中如何使用GCD更好的实现我们的需求 一.Synchronous & ...
- iOS开发之多线程技术—GCD篇
本篇将从四个方面对iOS开发中GCD的使用进行详尽的讲解: 一.什么是GCD 二.我们为什么要用GCD技术 三.在实际开发中如何使用GCD更好的实现我们的需求 一.Synchronous & ...
随机推荐
- JavaOne 2016——观众得以一睹JShell的威力
导读 在JavaOne 2016的主题演讲中,Java平台组的首席架构师Mark Reinhold指出Java 9并不仅仅是Jigsaw,针对Java 9,一共包含了85个JEP.我在这里会关注一个他 ...
- eclipse常用的字体
1.consolas 2.Segoe Script 3.Segoe Print 4.Courier New
- xml数据解析调研
XML数据解析http://www.tuicool.com/articles/Nraau2(必用) http://www.cnblogs.com/pengyingh/articles/2342699. ...
- POJ 2762 tarjan缩点+并查集+度数
Going from u to v or from v to u? Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 15494 ...
- 关于Linux下C编译错误(警告)cast from 'void*' to 'int' loses precision
char *ptr; //此后省略部分代码 ) //出错地方 那句话的意思是从 void* 到 int 的转换丢失精度,相信看到解释有些人就明白了, 此问题只会出现在X64位的Linux上,因为在64 ...
- NOIP2009解题报告
09年的题总体来说 没有难题,但是每道题除了第一题都要认真的慢慢写才能AC, 第一题: R国和S国正陷入战火之中,双方都互派间谍,潜入对方内部,伺机行动. 历经艰险后,潜伏于S国的R国间谍小C终于摸清 ...
- 使用windows服务和MSMQ和进行日志管理(解决高并发问题)
首先,建立一个windows服务项目 然后进行设计视图 在工作区空白处右属,添加一个安装项目 然后就可以写我们的代码了,我们的服务需要实时监视MSMQ的队列中有没有记录,如果有,就向数据库中插入 核心 ...
- 创建一个ROS msg
1. msg •msg:msg文件是简单的文本文件,用于描述ROS中消息(消息的各个参数项).用于为不同的编程语言生成有关消息的源代码. •srv:描述服务的文件,由两部分组成:请求和反馈: msg文 ...
- 阻止Infinitescroll.js无限滚动加载页面解决方法
由于某些原因,想终止当前页继续翻页的操作,可在Infinitescroll回调函数中将翻页事件取消. 代码如下: // -- 每页滚屏加载的页数-- var IpageItems = 5; var i ...
- 基于K2 BPM的大型连锁企业开关店选址管理解决方案
业内有句名言:“门店最重要的是什么?第一是选址,第二是选址,第三还是选址” 选址是一个很复杂的综合性商业决策过程,需要定性考虑和定向分析.K2开关店&选址管理方案重点关注:如何开出更好的店?在 ...