标签:
一、多线程概述
1、程序,进程,线程
2、单线程
3、多线程
4、单,多线程的区别
二、NSThread
实现多线程方式之一:NSThread,它是一个轻量级的多线程。它有以下两种创建方法:
#pragma mark - NSThread手动开辟子线程 // 参数1:target // 参数2:方法 // 参数3:传参 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(sayHi) object:nil]; [thread start]; // 使用NSThread和NSObject实现的开辟线程,系统会自动释放,所以不需要自己手动关闭。 // 结束线程的两种方式 // 取消线程(给线程发送结束消息,通过这个消息进行取消) [thread cancel]; // 立即结束线程 [NSThread exit]; #pragma mark - NSThread自动开辟子线程 // 线程自动开始 // 把手动开启的target和selector顺序颠倒 [NSThread detachNewThreadSelector:@selector(sayHi) toTarget:self withObject:nil]; // 获取当前线程 NSLog(@"current == %@", [NSThread currentThread]); // 获取主线程 NSLog(@"mainThread == %@", [NSThread mainThread]); // 判断当前线程是否为主线程 NSLog(@"isMainThread == %d", [NSThread isMainThread]);
NSObject中存在了一个最简单的后台执行的方法:
#pragma mark - NSObject开启子线程 /** * 开启子线程的方式之一:NSObject */ // 使用performSelectorInBackground开辟子线程 // 第一个参数:selector // 第二个参数:方法传递的参数 [self performSelectorInBackground:@selector(sayHi) withObject:@"test"]; - (void)sayHi { // 回到主线程 // 参数1:selector // 参数2:传参 // 参数3:是否等待子线程完成之后进入主线程 [self performSelectorOnMainThread:@selector(mainThreadChangeColor) withObject:nil waitUntilDone:YES]; }
三、NSOperationQueue
1、NSOperation
2、NSInvocationOperation
/** * NSOperation不能直接进行多线程的创建,需要借助:NSOperationQueue */ // 使用NSOperation的第一个子类去创建子线程:NSInvocationOperation NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(test) object:nil]; // 在单独使用NSOperation的子类去创建线程的时候,一定要启动才行 [operation start];
3、NSBlockOperation
//使用NSOperation的第二个子类创建子线程 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"我是block"); NSLog(@"-------%@", [NSThread currentThread]); NSLog(@"********%@", [NSThread mainThread]); }]; [blockOperation start];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
[queue addOperation:blockOperation];
4、NSOperationQueue
// 创建队列的对象 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 当值设置为1的时候,可以叫做串行:即顺序执行 // 当设置大于1的时候,叫做并行:多条通道同时进行各自的任务 queue.maxConcurrentOperationCount = 2; for (int i= 0; i < 10; i++) { NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"current = %@, da = %@, i = %d", [NSThread currentThread], [NSThread mainThread], i); }]; [queue addOperation:blockOperation]; }
四、GCD
1、GCD简介
2、GCD核心概念
3、GCD中两种队列(dispatch queue)
#pragma mark - 使用GCD去创建一个串行队列 // 第一种:系统提供的创建串行队列的方法 dispatch_queue_t queue = dispatch_get_main_queue();//在真正的开发中如果需要创建串行队列,比较习惯用这种 // 第二种:自己创建 // 参数1:系统提供的一个宏 // 参数2:是系统的保留字段 // 参数1和2可以互换位置,位置没有严格要求 dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_SERIAL, 0);
#pragma mark - 使用GCD去创建一个并行队列 // 第一种:系统提供的 // 参数1:优先级(有四个,没有明显的区别DISPATCH_QUEUE_PRIORITY_DEFAUL, DISPATCH_QUEUE_PRIORITY_HIGH, DISPATCH_QUEUE_PRIORITY_LOW, DISPATCH_QUEUE_PRIORITY_BACKGROUND ) // 参数2:系统的保留字段 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0); // 第二种:自己创建 // 参数1:表示创建队列的名字(苹果推荐使用反向域名去命名) // 参数2:系统提供的一个宏(队列的类型) dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
4、GCD功能
dispatch_async(queue, ^{ NSLog(@"currentThread = %@", [NSThread currentThread]); NSLog(@"mainThread = %@", [NSThread mainThread]); }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"3.0秒之后输出"); }); dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_apply(10, queue, ^(size_t index) { NSLog(@"%ld", index); });
// 创建一个分组 dispatch_group_t group = dispatch_group_create(); // 创建一个并行队列 dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT); dispatch_group_async(group, queue, ^{ NSLog(@"我是任务1"); }); dispatch_group_async(group, queue, ^{ NSLog(@"我是任务2"); }); dispatch_group_async(group, queue, ^{ NSLog(@"我是任务3"); }); // 用于监听所有任务的执行情况的(所以此功能代码必须放在所有任务之后书写) dispatch_group_notify(group, queue, ^{ NSLog(@"我是在所有任务之后执行的"); });
dispatch_barrier_async(queue, ^{
NSLog(@"我执行了");
});
+ (MyHandle *)sharedMyHandle { // 在GCD中只执行一次,用于记录内容是否执行过 static dispatch_once_t onceToken; // 保证多线程并发执行时只执行一次 dispatch_once(&onceToken, ^{ handle = [[MyHandle alloc] init]; }); return handle; }
// async 不等 block 体执行完。。就去执行下面的代码 // sync会等待 block 体执行完成之后,才会去执行 block 体外面的代码 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_sync(queue, ^{ NSLog(@"第一个任务"); }); NSLog(@"呵呵"); dispatch_sync(queue, ^{ NSLog(@"第二个任务"); }); NSLog(@"哈哈");
// 函数 void function(void * str){ NSLog(@"这是一个函数,%s",str); } // 第一个参数:队列 // 第二个参数:函数参数的内容 // 第三个参数:函数 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async_f(queue, @"passValue", function);
标签:
原文地址:http://www.cnblogs.com/soley/p/5503355.html