iOS中哪些技术可以实现开辟线程,他们之间的联系和区别是什么?
创建方式:
NSThread、NSOperation、GCD
联系:
三种编程方式都是针对线程操作来讲的,从上到下,抽象层次是从低到高,抽象程度越到的使用越简单;
区别:
(1)NSThread:
优点:NSThread比其他两个轻量级,使用简单
缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠以及唤醒等。线程同步对数据的加锁会有一定的系统开销
(2)NSOpearation:
— 不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上
— NSOpearation是面向对象的,给予OC语言实现的API。两种默认实现:NSInvocationOperation和NSBlockOperation。
(3)GCD:
— Grand Central Dispatch是有苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NStread,NSOperation的高效和强大的技术;
— GCD是基于C语言的API,提供了非常多强大的函数,GCD会自动管理线程的声明周期(创建线程、调度任务、销毁线程)。程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码。我们在编写GCD相关代码的时候,面对的函数,而不是方法。GCD中的函数大多数都以dispatch开头。
线程 和 进程
(1)进程:运行中的应用程序,操作系统称之为一个进程;编写->编译(.m->.o)->链接(把扇贝一部生成的.o文件连城引用程序);当用户启动应用程序,首先操作系统给启动的应用程序分配地址空间,然后把程序加载到代码段,操作系统再帮你生成一个主线程,用于执行代码(给它分配CPU)
(2)线程:是一个执行序列,是CPU分配的单位,如何分配靠操作系统的调度算法,线程必须存在于一个进程中,但是一个进程可以包含多个执行序列,也就是多个线程;
线程和进程的联系和区别
定义:
进程是系统进行资源分配和调度的一个独立单位;线程是进程的实体,是cpu调度和分派的基本单位;
关系:
一个线程可以创建和撤销另一个线程;同一个进程中的多个线程之间可以并发执行。
区别:
(1)简而言之,一个程序至少有一个进程,一个进程至少有一个线程
(2)线程的划分尺度小于进程,使得多线程程序的并发性高
(3)进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大的提高了程序的运行效率
(4)线程不能独立执行,必须依存于应用程序中,由应用程序提供多个线程执行控制
(5)多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统不会将多线程看做多个应用,来实现进程的调度和管理及资源分配。
一、NSThread:
创建一个线程,每一个线程都有一个入口函数,称之为线程函数,线程从线程函数开始执行,当一个线程的入口函数执行完毕,线程就会被操作系统回收;
隐式创建一条新的线程:
[self performSelectorInBackground:<#(nonnull SEL)#> withObject:<#(nullable id)#>];
线程间通讯(传值),不允许子线程中刷新UI
[self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>];
实例方法创建一个子线程,需要手动开启
NSThread *thread = [NSThread alloc] initWithTarget:<#(nonnull id)#> selector:<#(nonnull SEL)#> object:<#(nullable id)#>];
thread.name = @"子线程";
//启动线程
[thread start];
类方法开启一条新的线程,不需要手动开启,会直接执行方法
[NSThread detachNewThreadSelector:<#(nonnull SEL)#> toTarget:<#(nonnull id)#> withObject:<#(nullable id)#>];
其中参数:
/**
* detachNewThreadSelector 创建一个线程并自动执行
* SEL:线程的入口函数
* target:目标,在吗哥object的selector上作为线程的入口函数
* withObject:可以传递一个参数作为线程的参数
*
*/
/**
* 操作系统给线程分配CPU的参考因素:
* 1、时间片
* 2、优先级
* 3、线程的饥渴状态
* 4、线程nice值等
* 注意:不是优先级高就一定优先执行,CPU的调度室操作系统自己决定的,但是只要有一个线程,CPU就会分配
*/
GCD:
GCD:是iOS提供的对多核并发支持的一种多线程技术之一,NSOperation就是使用GCD来实现,GCD是以C语言的方式提供的,需要我们一block的形式提供服务;
CGD:默认是我们踢狗3中队列供我们使用,分别是主队列、全局并行队列、串行队列,我们只需要把我们的任务一block的形式提交到队列上
任务 && 队列
任务:同步(不开线程)和异步(开线程)
同步任务
dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
异步任务
dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
队列:串行(一个一个执行)和并行(一起执行)
1、主队列:主线程队列,在该队列中放置所有任务都在主线程执行,
2、全局并行队列:在队列上提交每个人物,都是生成一个线程,并行的执行,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
3、串行队列:在该队列上提交的任务,生成一个线程,在该线程上顺序执行,一个执行完成后下一个才能执行,
dispatch_queue_create(<#const char *label#>, <#dispatch_queue_attr_t attr#>)
主队列,不允许在主线程中提交同步任务,否则会死循环;dispatch_queue_t mainQueue = dispatch_get_main_queue();
同步:会卡死
异步:不会开线程,顺序执行
全局并发队列
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT , 0);
同步:不会开线程,顺序执行;
异步:会开线程,并且乱序执行
自定义串行队列
dispatch_queue_t SerialQueue = dispatch_queue_create("qf", NULL);
同步:不会开线程,顺序执行
异步:会开线程,顺序执行
自定义并行队列
dispatch_queue_t ConcurrentQueue = dispatch_queue_create("qf", DISPATCH_QUEUE_CONCURRENT);
同步:不会开线程,顺序执行
异步:会开线程,乱序执行
从子线程切换到主线程的方法
1、self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#>
waitUntilDone:<#(BOOL)#>
2、[NSOperationQueue mainQueue] addOperation:<#(nonnull NSOperation *)#>
3、dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)