NSThread那些事儿
NSThread
哎呀,它面向对象,再去看看苹果提供的API,对比一下Pthreads,简单明了,人生仿佛又充满了阳光和希望,我们先来一看一下系统提供给我们的API自然就知道怎么用了,来来来,我给你注释一下啊:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
@interface NSThread : NSObject//当前线程@property (class, readonly, strong) NSThread *currentThread;//使用类方法创建线程执行任务+ (void)detachNewThreadWithBlock:(void (^)(void))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;//判断当前是否为多线程+ (BOOL)isMultiThreaded;//指定线程的线程参数,例如设置当前线程的断言处理器。@property (readonly, retain) NSMutableDictionary *threadDictionary;//当前线程暂停到某个时间+ (void)sleepUntilDate:(NSDate *)date;//当前线程暂停一段时间+ (void)sleepForTimeInterval:(NSTimeInterval)ti;//退出当前线程+ (void)exit;//当前线程优先级+ (double)threadPriority;//设置当前线程优先级+ (BOOL)setThreadPriority:(double)p;//指定线程对象优先级 0.0~1.0,默认值为0.5@property double threadPriority NS_AVAILABLE(10_6, 4_0);//服务质量@property NSQualityOfService qualityOfService NS_AVAILABLE(10_10, 8_0);//线程名称@property (nullable, copy) NSString *name NS_AVAILABLE(10_5, 2_0);//栈区大小@property NSUInteger stackSize NS_AVAILABLE(10_5, 2_0);//是否为主线程@property (class, readonly) BOOL isMainThread NS_AVAILABLE(10_5, 2_0);//获取主线程@property (class, readonly, strong) NSThread *mainThread NS_AVAILABLE(10_5, 2_0);//初始化- (instancetype)init NS_AVAILABLE(10_5, 2_0) NS_DESIGNATED_INITIALIZER;//实例方法初始化,需要再调用start方法- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument NS_AVAILABLE(10_5, 2_0);- (instancetype)initWithBlock:(void (^)(void))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));//线程状态,正在执行@property (readonly, getter=isExecuting) BOOL executing NS_AVAILABLE(10_5, 2_0);//线程状态,正在完成@property (readonly, getter=isFinished) BOOL finished NS_AVAILABLE(10_5, 2_0);//线程状态,已经取消@property (readonly, getter=isCancelled) BOOL cancelled NS_AVAILABLE(10_5, 2_0);//取消,仅仅改变线程状态,并不能像exist一样真正的终止线程- (void)cancel NS_AVAILABLE(10_5, 2_0);//开始- (void)start NS_AVAILABLE(10_5, 2_0);//线程需要执行的代码,一般写子类的时候会用到- (void)main NS_AVAILABLE(10_5, 2_0);@end另外,还有一个NSObject的分类,瞅一眼:@interface NSObject (NSThreadPerformAdditions)//隐式的创建并启动线程,并在指定的线程(主线程或子线程)上执行方法。- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<nsstring *> *)array;- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<nsstring *> *)array NS_AVAILABLE(10_5, 2_0);- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg NS_AVAILABLE(10_5, 2_0);@end</nsstring *></nsstring *> |
上面的介绍您还满意吗?小的帮您下载一张图片,您瞧好:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
-(void)creatBigImageView{ self.bigImageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:_bigImageView]; UIButton *startButton = [UIButton buttonWithType:UIButtonTypeSystem]; startButton.frame = CGRectMake(0, 0, self.view.frame.size.width / 2, 50); startButton.backgroundColor = [UIColor grayColor]; [startButton setTitle:@"开始加载" forState:UIControlStateNormal]; [startButton addTarget:self action:@selector(loadImage) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:startButton]; UIButton *jamButton = [UIButton buttonWithType:UIButtonTypeSystem]; jamButton.frame = CGRectMake(self.view.frame.size.width / 2, 0, self.view.frame.size.width / 2, 50); jamButton.backgroundColor = [UIColor grayColor]; [jamButton setTitle:@"阻塞测试" forState:UIControlStateNormal]; [jamButton addTarget:self action:@selector(jamTest) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:jamButton];}-(void)jamTest{ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"线程阻塞" message:@"" delegate:nil cancelButtonTitle:@"好" otherButtonTitles:nil, nil]; [alertView show];}-(void)loadImage{ NSURL *imageUrl = [NSURL URLWithString:@"http://img5.duitang.com/uploads/item/201206/06/20120606174422_LZSeE.thumb.700_0.jpeg"]; NSData *imageData = [NSData dataWithContentsOfURL:imageUrl]; [self updateImageData:imageData];}-(void)updateImageData:(NSData*)imageData{ UIImage *image = [UIImage imageWithData:imageData]; self.bigImageView.image = image;} |
运行结果:

我们可以清楚的看到,主线程阻塞了,用户不可以进行其他操作,你见过这样的应用吗?
所以我们这样改一下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
-(void)creatBigImageView{ self.bigImageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; [self.view addSubview:_bigImageView]; UIButton *startButton = [UIButton buttonWithType:UIButtonTypeSystem]; startButton.frame = CGRectMake(0, 20, self.view.frame.size.width / 2, 50); startButton.backgroundColor = [UIColor grayColor]; [startButton setTitle:@"开始加载" forState:UIControlStateNormal]; [startButton addTarget:self action:@selector(loadImageWithMultiThread) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:startButton]; UIButton *jamButton = [UIButton buttonWithType:UIButtonTypeSystem]; jamButton.frame = CGRectMake(self.view.frame.size.width / 2, 20, self.view.frame.size.width / 2, 50); jamButton.backgroundColor = [UIColor grayColor]; [jamButton setTitle:@"阻塞测试" forState:UIControlStateNormal]; [jamButton addTarget:self action:@selector(jamTest) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:jamButton];}-(void)jamTest{ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"阻塞测试" message:@"" delegate:nil cancelButtonTitle:@"好" otherButtonTitles:nil, nil]; [alertView show];}-(void)loadImageWithMultiThread{ //方法1:使用对象方法 //NSThread *thread=[[NSThread alloc]initWithTarget:self selector:@selector(loadImage) object:nil]; //??启动一个线程并非就一定立即执行,而是处于就绪状态,当CUP调度时才真正执行 //[thread start]; //方法2:使用类方法 [NSThread detachNewThreadSelector:@selector(loadImage) toTarget:self withObject:nil];}-(void)loadImage{ NSURL *imageUrl = [NSURL URLWithString:@"http://img5.duitang.com/uploads/item/201206/06/20120606174422_LZSeE.thumb.700_0.jpeg"]; NSData *imageData = [NSData dataWithContentsOfURL:imageUrl]; //必须在主线程更新UI,Object:代表调用方法的参数,不过只能传递一个参数(如果有多个参数请使用对象进行封装),waitUntilDone:是否线程任务完成执行 [self performSelectorOnMainThread:@selector(updateImageData:) withObject:imageData waitUntilDone:YES]; //[self updateImageData:imageData];}-(void)updateImageData:(NSData*)imageData{ UIImage *image = [UIImage imageWithData:imageData]; self.bigImageView.image = image;} |
运行结果:

哎呀,用多线程果然能解决线程阻塞的问题,并且NSThread也比Pthreads好用,仿佛你对精通熟练使用多线程又有了一丝丝曙光。假如我有很多不同类型的任务,每个任务之间还有联系和依赖,你是不是又懵逼了,上面的你是不是觉得又白看了,其实开发中我觉得NSThread用到最多的就是[NSThread currentThread];了。(不要慌,往下看... ...)

转自:http://www.cocoachina.com/ios/20170829/20404.html
NSThread那些事儿的更多相关文章
- 说说Makefile那些事儿
说说Makefile那些事儿 |扬说|透过现象看本质 工作至今,一直对Makefile半知半解.突然某天幡然醒悟,觉得此举极为不妥,只得洗心革面从头学来,以前许多不明觉厉之处顿时茅塞顿开,想想好记性不 ...
- 总结iOS开发中的断点续传那些事儿
前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...
- setTimeout那些事儿
一.setTimeout那些事儿之单线程 一直以来,大家都在说Javascript是单线程,浏览器无论在什么时候,都且只有一个线程在运行JavaScript程序. 但是,不知道大家有疑问没——就是我们 ...
- Javascript中关于cookie的那些事儿
Javascript-cookie 什么是cookie? 指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密).简单点来说就是:浏览器缓存. cookie由什 ...
- 4.1/4.2 多线程进阶篇<上>(Pthread & NSThread)
本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书” 本文源码 Demo 详见 Githubhttps://github.com/shorfng ...
- webpack那些事儿
webpack那些事儿01-webpack到底是什么 webpack那些事儿02-从零开始 webpack那些事儿03-热插拔 hot webpack那些事儿04-spa项目实战分析 webpack那 ...
- iOS开发之多线程技术(NSThread、OperationQueue、GCD)
在前面的博客中如果用到了异步请求的话,也是用到的第三方的东西,没有正儿八经的用过iOS中多线程的东西.其实多线程的东西还是蛮重要的,如果对于之前学过操作系统的小伙伴来说,理解多线程的东西还是比较容易的 ...
- 关于JSON的那些事儿
JSON的那些事儿 曾经有一段时间,XML是互联网上传输结构化数据的事实标准,其突出特点是服务器与服务器间的通信.但是业内不少人认为XML过于繁琐.冗长,后面为了解决这个问题也出现了一些方案,但是由于 ...
- iOS多线程之3.NSThread的线程间通信
我们把一些耗时操作放在子线程,例如下载图片,但是下载完毕我们不能在子线程更新UI,因为只有主线程才可以更新UI和处理用户的触摸事件,否则程序会崩溃.此时,我们就需要把子线程下载完毕的数据传递到主线 ...
随机推荐
- Markdown快速上手指南
Markdown快速上手指南 1.Markdown介绍 markdown可以实现快速html文档编辑,格式优没,并且不需要使用html元素. markdown采用普通文本的形式,例如读书笔记等易于使用 ...
- mysql : 修改数据库权限
解决步骤 第一步,点击用户 注意!!! 编辑权限,在我们设置权限之前,我们需要先重新加载才能生效, 如果不用编辑的话,直接按重新载入编辑,这个相当于保存. 中文意思(注意看那段话) 第二步 选择要处理 ...
- mysql语句的相关操作整理
事实证明,如果不经常跟代码,语句打交道,人家可是会翻脸不认人的,大脑也会觉得一脸懵逼,不知道做错了啥,这次长点记性了,把语句整理出来,不仅加强对sql语句的记忆,还能有个笔记,以后大脑懵逼了还能回来看 ...
- POJ-1422 Air Raid---二分图匹配&最小路径覆盖
题目链接: https://vjudge.net/problem/POJ-1422 题目大意: 有n个点和m条有向边,现在要在点上放一些伞兵,然后伞兵沿着图走,直到不能走为止 每条边只能是一个伞兵走过 ...
- Android 编辑框(EditText)属性学习
EditText的属性很多,这里介绍几个:android:hint="请输入数字!"//设置显示在空间上的提示信息android:numeric="integer&quo ...
- 【CCPC-Wannafly Winter Camp Day4 (Div1) G】置置置换(动态规划)
点此看题面 大致题意: 求出有多少个长度为\(n\)的排列满足对于奇数位\(a_{i-1}<a_i\),对于偶数位\(a_{i-1}>a_i\). 考虑打表? 考虑每次只有一个数\(n\) ...
- Centos 5.5 编译安装mysql 5.5.9
下载mysql wget http://mysql.mirrors.pair.com/Downloads/MySQL-5.5/mysql-5.5.9.tar.gz 创建mysql用户 [root@x ...
- Matlab 绘图实例
概要 每次用 Matlab 绘图都要搜一堆资料设置一些参数,本次将绘图中的一些参数设置实例展示在这里,以备不时之需.暂包括折线图,面积图. 折线图实例 下图是效果图: 图 1:折线图效果图 ...
- redux详解
redux介绍 学习文档:英文文档,中文文档,Github redux是什么 redux是一个独立专门用于做状态管理的JS库(不是react插件库),它可以用在react, angular, vue等 ...
- 测试 jdbc 中连接关闭的时机
测试 jdbc 中连接关闭的时机 写一段程序,测试 jdbc 连接的关闭情况 /** * 测试 jdbc 连接的关闭情况 */ public static void testOpenCon(){ // ...