iOS 线程GCD等

2020-04-21  本文已影响0人  leesen

介绍:

         网络请求、图片下载、文件处理、数据存储、任务执行

         串行: 任务一个任务一个的进行,时间之和, 队列相关

         并行: 任务同时进行,

         同步:线程阻塞,任务执行完成之后才会执行下一个

         异步:不知道什么时候返回,不会阻塞其他任务

         1 进程 线程

         线程是任务执行的基本单元. 进程中所有任务通过线程来完成

         单核 时间片轮转,分配时间片交替执行,宏观上并发执行

         多核

         2 技术方案

         PThread 基于C++,用的少

         NSThread

         GCD

         NSOperation  NSOperationQueue

         -1, PThread基于C++语言开发使用的,

         -2, NSThread,基于OC开发,苹果封装好的,面向对象的实现的.  3种方式创建

         初始化: 通过[alloc]initwithTarget开辟子线程  start方法

         通过detachNewThreadSelector toTarget 方式创建并执行线程, 静态方法,类方法

         通过performSelectInBackground 方式创建线程

         [self performSelect:onThread:]

         [self performSelectInBackground : WithObject:] 子线程  sleep(1)

         [self performSelectOnMainThread: WithObject:] 主线程

         属性方法:

         name,

         setThreadPriority 优先级 0 - 1 之间

         线程锁 买票系统模拟 3种方式

         关键词: synchronized

         [NSCondition lock]

         NSLock

         3 GCD 自动管理线程生命周期 线程池,OC语法,block,方便灵活, 

         -1,

         global_queue: 全局并发 参数: long型 , 可以设置优先级low high default

         main_queue 主线程 UI线程

         dispatch_async(dispatch_get_ global_queue(0,0),^{

         [NSThread sleepForTimeInverval:3]

         get_main_queue 刷新UI

         })

         -2,

         串行queue, 保证线程顺序执行, 一个线程中串行执行

         dispatch_queue_create : 参数1: 名字,  参数2: NULL(SERIAL)和CONCURRENT, 串行和并行队列

         CONCURRENT 是多个线程并发

         -3 dispatch_group_ 多个任务异步处理,回调通知,处理其他业务, 异步请求的统一回调

         创建queue, CONCURRENT并行,

         创建dispatch_group

         情况一: 线程内部 正常同步执行

         dispatch_group_async(group, queue)^{

         request1

         [NSThread sleepForTimeInverval:3]

         }

         dispatch_group_async(group, queue)^{

         request2

         [NSThread sleepForTimeInverval:3]

         }

         dispatch_group_async(group, queue)^{

         request3

         [NSThread sleepForTimeInverval:3]

         }

         拿到所有task结束之后的回调, 回来是在异步线程

         dispatch_group_notify(group,queue, ^{

            "All tasks over"

         })

         情况二: 线程内部,又开辟异步线程,比如网络请求

         就用以下解决

         dispatch_group_enter(group);

         dispatch_group_leave(group); 异步回来之后, 释放掉 request被group持有

         -4 信号量 dispatch_semaphore_signal

iOS信号量的理解和使用 - 简书

iOS GCD信号量的使用 - 简书

使用场景

主要是控制线程并发数

阻塞请求

第一个函数是创建一个信号量。每一个信号量都有一个计数,该函数唯一的参数就是该信号量的初始计数值。

第二个函数每调用一次,信号量的计数会增加1。在调用该函数之前信号量的计数小于0,那么该函数会唤醒一个等待第三个函数返回的线程。

第三个函数每调用一次,信号量的计数会减小1.在调用该函数之后,如果信号量的计数值不小于0,那么该函数会立即返回;如果小于0,会等待,直到被第二个函数发出信号。如果有多个函数在等待信号,那么按照先后顺序依次获得信号。

         // dispatch_semaphore_signal有两类用法:a、解决同步问题;b、解决有限资源访问(资源为1,即互斥)问题。

         // dispatch_semaphore_wait,若semaphore计数为0则等待,大于0则使其减1。

         // dispatch_semaphore_signal使semaphore计数加1。

         // a、同步问题:输出肯定为1、2、3。

       5. 倒计时

         //NSEC_PER_SEC是秒,*1是每秒

         dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), NSEC_PER_SEC * 1, 0);

         //设置响应dispatch源事件的block,在dispatch源指定的队列上运行

         dispatch_source_set_event_handler(timerQueue, ^{

         其他:

         -1 单例:dispatch_once_t, 整个生命周期只执行一次

         -2 延迟执行: dispatch_after(DISPATCH_TIME_NOW,(int64_tF)(2*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

         });  避开一个方法.  缺点: 不能cancel, 页面已经释放掉, 容易崩溃.  可以设置一个变量. yes no不执行

         dispatch_suspend(queue); //暂停队列queue

         dispatch_resume(queue);  //恢复队列queue

         barri  多组任务

         倒计时

1.关于GCD倒计时,实际开发中遇到的问题在于线程使用,要知道倒计时每次改变都是在主线程对按钮的UI进行重新绘制,所以必须保证倒计时按钮变化的通知,其他操作要在其他线程,否则,页面卡死,卡顿将会出现

2.一般用到倒计时,大多是在收取验证码,当收到验证码,填写完毕的时候,点击进行其他操作,必须杀死/停止当前线程,否则只能等到倒计时为0方可进行,道理就是如1所描述     

   iOS开发之倒计时显示(GCD) 

         4 NSOperation NSOperationQueue  NSBlockOperation

         创建使用 main方法

         最大并发数 线程池  setMaxConcurrentOperationCount:

         依赖:[OperA addDependency: OperB]  先执行B.

         如果是异步执行,需要runLoop去控制执行. 当前任务操作完之后, 再执行其他线程

         NSRunloop 循环监听状况,线程不会自动结束, 除非手动要求结束

参考:

GCD底层原理 - 简书

最浅显易懂的iOS多线程技术 - GCD的教程 - 简书

iOS GCD 使用指南 - 简书

上一篇 下一篇

猜你喜欢

热点阅读