ios中的多线程
2016-03-08 00:57
295 查看
主线程:线程是进程的基本执行单元,一个iOS程序运行后,默认会开启1条线程,称为“主线程”又叫“UI线程”
主线程的主要作用
1.显示\刷新UI界面
2.处理UI事件(比如点击事件、滚动事件、拖拽事件等)
的框架,使用起来这酸爽!感受一下
到了这里也许你还会问 到底这个线程到底操作了什么 别急 跟着小龙哥看下一个
注意:
Note: The performSelector: method and related selector-invoking methods are not imported in Swift because they are inherently unsafe.
因为安全问题 苹果在swift中取消了performSelector这个方法
他最伟大的优点在于它会自动管理线程的生命周期(创建线程、调度任务、销毁线程)使用起来非常方便
任务:即操作,你想要干什么,说白了就是一段代码,在 GCD 中就是一个 Block,所以添加任务十分方便。任务有两种执行方式: 同步执行 和 异步执行,他们之间的区别是 是否会创建新的线程。
同步(sync) 和 异步(async) 的主要区别在于会不会阻塞当前线程,直到 Block 中的任务执行完毕!
如果是 同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行。
如果是 异步(async)操作,当前线程会直接往下执行,它不会阻塞当前线程。
队列:用于存放任务。一共有两种队列, 串行队列 和 并行队列
自己创建的队列:
自己可以创建 串行队列, 也可以创建 并行队列。第二个参数用来表示创建的队列是串行的还是并行的
2.1创建串行队列
DISPATCH_QUEUE_SERIAL 或 NULL 表示
2.2创建并行队列
-DISPATCH_QUEUE_CONCURRENT
异步任务:不会阻塞当前线程 (ASYNC)
NSOperationQueue 分别对应 GCD 的 任务 和 队列 。操作步骤也很好理解
主线程的主要作用
1.显示\刷新UI界面
2.处理UI事件(比如点击事件、滚动事件、拖拽事件等)
iOS有四个多线程解决方案
一. Pthreads
这是一套在很多操作系统上都通用的多线程API,所以移植性很强(然并卵),当然在 iOS 中也是可以的。不过这是基于 c语言的框架,使用起来这酸爽!感受一下
1.包含头文件
#import <pthread.h>
2.创建线程,并执行任务
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { pthread_t thread; //创建一个线程并自动执行 pthread_create(&thread, NULL, start, NULL); } void *start(void *data) { NSLog(@"%@", [NSThread currentThread]); return NULL; }
到了这里也许你还会问 到底这个线程到底操作了什么 别急 跟着小龙哥看下一个
二.NSThread
经过苹果封装后的,并且完全面向对象的。所以你可以直接操控线程对象,非常直观和方便。但是,它的生命周期还是需要我们手动管理,所以这套方案也是偶尔用用,比如 [NSThread currentThread],它可以获取当前线程类,你就可以知道当前线程的各种属性,用于调试十分方便。下面来看看它的一些用法。1.创建启动异步
// 创建 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil]; // 启动 [thread start];
2.创建启动同步完成
1.直接创建并自动启动 [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:nil];
2.使用 NSObject 的方法创建并自动启动 [self performSelectorInBackground:@selector(run:) withObject:nil];
注意:
Note: The performSelector: method and related selector-invoking methods are not imported in Swift because they are inherently unsafe.
因为安全问题 苹果在swift中取消了performSelector这个方法
3.NSThread常用方法
除了创建启动外,NSThread 还以很多方法,下面我列举一些常见的方法,当然我列举的并不完整,更多方法大家可以去类的定义里去看。//取消线程 - (void)cancel; //启动线程 - (void)start; //判断某个线程的状态的属性 @property (readonly, getter=isExecuting) BOOL executing; @property (readonly, getter=isFinished) BOOL finished; @property (readonly, getter=isCancelled) BOOL cancelled; //设置和获取线程名字 -(void)setName:(NSString *)n; -(NSString *)name; //获取当前线程信息 + (NSThread *)currentThread; //获取主线程信息 + (NSThread *)mainThread; //使当前线程暂停一段时间,或者暂停到某个时刻 + (void)sleepForTimeInterval:(NSTimeInterval)time; + (void)sleepUntilDate:(NSDate *)date;
三.GCD
Grand Central Dispatch 主要的线程优化技术他最伟大的优点在于它会自动管理线程的生命周期(创建线程、调度任务、销毁线程)使用起来非常方便
1.如何使用GCD
首先我们要明白两个非常重要的概念任务:即操作,你想要干什么,说白了就是一段代码,在 GCD 中就是一个 Block,所以添加任务十分方便。任务有两种执行方式: 同步执行 和 异步执行,他们之间的区别是 是否会创建新的线程。
同步(sync) 和 异步(async) 的主要区别在于会不会阻塞当前线程,直到 Block 中的任务执行完毕!
如果是 同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行。
如果是 异步(async)操作,当前线程会直接往下执行,它不会阻塞当前线程。
队列:用于存放任务。一共有两种队列, 串行队列 和 并行队列
2.创建队列
1.主队列dispatch_queue_t queue = ispatch_get_main_queue();
自己创建的队列:
自己可以创建 串行队列, 也可以创建 并行队列。第二个参数用来表示创建的队列是串行的还是并行的
2.1创建串行队列
DISPATCH_QUEUE_SERIAL 或 NULL 表示
2.2创建并行队列
-DISPATCH_QUEUE_CONCURRENT
//串行队列 dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", NULL); dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_SERIAL); //并行队列 dispatch_queue_t queue = dispatch_queue_create("tk.bourne.testQueue", DISPATCH_QUEUE_CONCURRENT);
3.全局并行队列
只要是并行任务一般都加入到这个队列。这是系统提供的一个并发队列。dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
3.创建任务
同步任务:会阻塞当前线程 (SYNC)dispatch_sync(<#queue#>, ^{ //code here NSLog(@"%@", [NSThread currentThread]); });
异步任务:不会阻塞当前线程 (ASYNC)
dispatch_async(<#queue#>, ^{ //code here NSLog(@"%@", [NSThread currentThread]); });
4.队列组
队列组可以将很多队列添加到一个组里,这样做的好处是,当这个组里所有的任务都执行完了,队列组会通过一个方法通知我们。下面是使用方法,这是一个很实用的功能。//1.创建队列组 dispatch_group_t group = dispatch_group_create(); //2.创建队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //3.多次使用队列组的方法执行任务, 只有异步方法 //3.1.执行3次循环 dispatch_group_async(group, queue, ^{ for (NSInteger i = 0; i < 3; i++) { NSLog(@"group-01 - %@", [NSThread currentThread]); } }); //3.2.主队列执行8次循环 dispatch_group_async(group, dispatch_get_main_queue(), ^{ for (NSInteger i = 0; i < 8; i++) { NSLog(@"group-02 - %@", [NSThread currentThread]); } }); //3.3.执行5次循环 dispatch_group_async(group, queue, ^{ for (NSInteger i = 0; i < 5; i++) { NSLog(@"group-03 - %@", [NSThread currentThread]); } }); //4.都完成后会自动通知 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"完成 - %@", [NSThread currentThread]); });
四 NSOperation & NSOperationQueue
NSOperation 是苹果公司对 GCD 的封装,完全面向对象,所以使用起来更好理解。 大家可以看到 NSOperation 和NSOperationQueue 分别对应 GCD 的 任务 和 队列 。操作步骤也很好理解
五 NSOperation & NSOperationQueue
我们进行完多线程操作或 都需要回到主线程 接下来 就是讲到上面的四种方法是如何回到主线程(UI线程逻辑中的)5.1 NSThread
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:NO];
5.2 GCD
dispatch_async(dispatch_get_main_queue(), ^{ });
5.3 NSOperationQueue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ }];
相关文章推荐
- iOS开发技巧:设置导航栏全透明效果
- iOS学习 用scrollView 制作相册album 涉及双击事件
- iOS中userdefault的使用[转]
- 为什么说 iPhone 是相对更安全的手机之一?
- iOS多线程归纳
- ios 有如下三种随机数方法:
- iOS常用CGRect的交错,边缘,中心的检测
- iOS 根据日期判断星座源代码
- IOS 本地存储
- IOS博客项目搭建-08-项目使用本地Git
- ios SDWebImage 图片缓存运用
- runtime 运行时机制 完全解读
- 今天开通博客,记录一下IOS学习历程
- 【iOS开发系列】escape编码
- iOS屏幕旋转
- iOS----------SDWebimage源码解析(2)
- iOS多线程之NSThread
- iOS百度地图的相关开发(一)
- 开源代码分析之Android/iOS Hybrid JSBridge框架
- iOS多线程之pthread