Object C中创建线程的方法有NSThread,GCD, NSOperation
为什么80%的码农都做不了架构师?>>>
线程创建有三种方法:使用NSThread创建、使用GCD的dispatch、使用子类化的NSOperation,然后将其加入NSOperationQueue;在主线程执行代码,方法是performSelectorOnMainThread,如果想延时执行代码可以用performSelector:onThread:withObject: afterDelay: 或者使用GCD的函数:
1、常用的方法dispatch_async
为了避免界面在处理耗时的操作时卡死,比如读取网络数据,IO,数据库读写等,我们会在另外一个线程中处理这些操作,然后通知主线程更新界面。
用GCD实现这个流程的操作比前面介绍的NSThread NSOperation的方法都要简单。代码框架结构如下:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 耗时的操作 dispatch_async(dispatch_get_main_queue(), ^{ // 更新界面 });
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"]; NSData * data = [[NSData alloc]initWithContentsOfURL:url]; UIImage *image = [[UIImage alloc]initWithData:data]; if (data != nil) { dispatch_async(dispatch_get_main_queue(), ^{ self.imageView.image = image; }); }
});
是不是代码比NSThread NSOperation简洁很多,而且GCD会自动根据任务在多核处理器上分配资源,优化程序。
系统给每一个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列,如下:
dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
这里也用到了系统默认就有一个串行队列main_queue
dispatch_queue_t mainQ = dispatch_get_main_queue();
虽然dispatch queue是引用计数的对象,但是以上两个都是全局的队列,不用retain或release。
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");
});
dispatch_release(group);
dispatch_group_async是异步的方法,运行后可以看到打印结果:
2012-09-25 16:04:16.737 gcdTest[43328:11303] group1
2012-09-25 16:04:17.738 gcdTest[43328:12a1b] group2
2012-09-25 16:04:18.738 gcdTest[43328:13003] group3
2012-09-25 16:04:18.739 gcdTest[43328:f803] updateUi
每个一秒打印一个,当第三个任务执行后,upadteUi被打印。
3、dispatch_barrier_async的使用
dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行
例子代码如下:
dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:2]; NSLog(@"dispatch_async1");
});
dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:4]; NSLog(@"dispatch_async2");
});
dispatch_barrier_async(queue, ^{ NSLog(@"dispatch_barrier_async"); [NSThread sleepForTimeInterval:4]; });
dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"dispatch_async3");
});
打印结果:
2012-09-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async
2012-09-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3
请注意执行的时间,可以看到执行的顺序如上所述。
4、dispatch_apply
执行某个代码片段N次。
dispatch_apply(5, globalQ, ^(size_t index) {
// 执行5次
});
5、dispatch_after
//2秒后异步执行这里的代码...
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
});
转载于:https://my.oschina.net/aprill/blog/545917
Object C中创建线程的方法有NSThread,GCD, NSOperation相关推荐
- Linux设备驱动程序中创建线程的方法
参考博客文章来源:https://blog.csdn.net/ezimu/article/details/60467017 第一种方法:kernel_thread #include <linux ...
- JAVA中创建线程的三种方法及比较
JAVA中创建线程的方式有三种,各有优缺点,具体如下: 目录 一.继承Thread类来创建线程 二.实现Runnable接口来创建线程 三.通过Callable和Future来创建线程 四.三种方式创 ...
- JAVA中创建线程池的五种方法及比较
之前写过JAVA中创建线程的三种方法及比较.这次来说说线程池. JAVA中创建线程池主要有两类方法,一类是通过Executors工厂类提供的方法,该类提供了4种不同的线程池可供使用.另一类是通过Thr ...
- java中创建线程的四种方式及线程池详解
众所周知,我们在创建线程时有四种方法可以用,分别是: 1.继承Thread类创建线程 2.实现Runnable接口创建线程 3.使用Callable和Future创建线程 4.使用线程池创建(使用ja ...
- 陈硕智能指针线程安全_C++ 创建线程的方法
C++开发过程中,创建线程是必不可少的,今天就给大家说说c++创建线程的方法,主要介绍我常用的2种方法. 第一种:CreateThread HANDLE WINAPI CreateThread( t ...
- Object类中的两个方法——wait和notify使用总结
Object类中的wait .和 notify方法是用来处理线程的方法,既然定义在Object类中,两个方法的重要程度可见一斑: 两个方法的使用上都很复杂:通过阅读API获得更多对方法的理解: The ...
- java 线程中创建线程_如何在Java 8中创建线程安全的ConcurrentHashSet?
java 线程中创建线程 在JDK 8之前,还没有办法在Java中创建大型的线程安全的ConcurrentHashSet. java.util.concurrent包甚至没有一个名为Concurren ...
- Java中创建线程的三种方式
Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)继承Thread类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. ...
- windows系统中创建线程常用哪几个函数,有什么区别?
windows系统中创建线程常用哪几个函数? 在windows系统中创建线程的函数有: CreadThread,AfxBeginThread,_beginthread,_beginthreadex. ...
- Java-线程-创建线程的方法
public class ThreadMain {/*** @param args*/public static void main(String[] args) {/*** 创建thread的子类, ...
最新文章
- think in Java 第五章之垃圾回收类型
- 使用Redis来实现LBS的应用
- c语言学习笔记-if语句块一定要加分号
- 【Java源码分析】LinkedList源码分析
- vuepress 2.x 集成 element-plus
- SQL SERVER数据库多条件查询
- js 短信验证码 6位数字
- 欧拉:他停止了生命和计算
- html5酷炫表白代码_七夕表白代码,樱花特效+爱心特效+花瓣+评论留言功能等
- phpstorm2017破解方法
- ERP系统之JPJDE入门-1 JDE 简史
- 可道云访问服务器其他文件,可道云怎么用_可道云使用功能解析
- 1.8 收集的XSS Payload
- 用Python爬取微信好友头像,才知道好友都是这样的人
- 华为matebook鸿蒙,16寸专业大屏+满血Zen3!华为MateBook 16评测:鸿蒙加持 平板变身新外设...
- webpack 打包错误
- 【PPic】基于Electron+Vue+iView的图床应用设计
- 超级课程表导入课程显示服务器繁忙,超级课程表 导入不了课表怎么办详解导入课程表教程...
- 一小时快速上手win10 docker 、vscode、MobaXterm、git协作开发
- 青云科技以开放姿态打造低代码平台