进程: 一个运行着的app称为一个进程 一个进程里面有多个线程 进程排好 里面有多个线程也排好 CPU开始不停地来回跑接受线程计算的结果 提交 线程创建会花成本 而且线程太多 CPU也会跑的太累 效率也会降下来 一个一个的小作坊就是进程 里面的工人就是线程 有一个老大成为主线程 工人干活(有成本) 不过得等待CPU跑到这里才能提交完成的任务 cpu会在每个工人那里停一下
主线程: 来处理紧急任务的 优先级最高 当主线程的里面任务发生时,子线程的任务会终止,Cpu直接去主线程那里接收完成的紧急任务 UI任务要放在主线程,因为用户点击了,要立即响应 耗时任务要放在子线程 如果放在主线程 因为主线程里面的任务执行时串行的, 那么我的点击任务可能要等你执行完才响应 肯定不行
打印布尔值 %ld %zd
Thread属性 : name priority
NSThread创建线程对象的三种方式:
1> alloc init 可以获取到线程对象 有一个NSThread指针指向线程对象,可以设置线程的名字,优先级 需要手动开启
2> detach 不能获取线程对象 当然就不能设置线程名字,优先级 不需要手动开启
3>self performSelectorInBackground 不能获取线对象 也不能设置线程名字,优先级 不需要手动开启
这样来理解线程对象: 每一个线程创建都会伴随着一个方法 , 线程的生命周期是,方法执行完毕,然后线程对象销毁 CPU同一时刻只能有一个线程在运行 每一个线程是调度的基本单位 如果我的app线程多,那么我的app总体的分配的时间就多,效率就高 线程太多的缺点也不用赘述
线程对象的生命周期: 创建————————>(就绪(可调度线程池), 运行 ,阻塞(阻塞的时候被拿到内存中))————————>死亡 在他的任务完成后就会死亡 ,如果想要用代码让 线程阻塞 或者死亡 得在任务中执行
线程死亡的两种方式: +(void) exit 或者 break;
线程阻塞的方式: + (void) sleep…….
线程开始 start
当多个线程来访问同一个资源的时候,此时要加锁实现线程同步,同一个资源只允许一个线程来访问 @synchronized (对象)里面的参数对象得是全局唯一的 互斥访问
atomic: 原子性 会为属性的set方法加锁 线程安全 耗费性能
nonatomic: 非原子性 不会为属性的set方法加锁 非线程安全 适合移动开发
在IOS开发中 访问互斥资源的场景很少 所以属性的声明都用nonatomic ,实在用到的时候再去改
获取代码行的当前时间: NSDate 或者 CFTimeInterval(CoreFoundation里面的)
线程间通信: 就是线程间传数据
[self.imageView(1) performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO] 传给任意线程 也可以直接传给主线程 on mainThread 整个方法代表着: 传给某个线程某个数据 然后 执行1的方法 谁performSelector就执行谁的方法
GCD
Grand Center Dispatch 牛逼的中枢调度器 纯C语言 多核并行解决方案 可以自动管理线程,解放程序员,不用写线程管理的代码
核心概念: 任务 队列 任务在队列里面 队列安排任务的执行
完成任务的函数: 同步函数 只能在当前线程完成任务
异步函数 可以在新的线程中完成任务,具备开启新的线程的能力 (具体开几个线程是由GCD决定的)
队列的类型: 并发队列 可以同时队列里的执行任务 可以创建 可以获得
串行队列 执行完一个任务,执行下一个 可以创建 可以获得主队列
函数类型 加 队列类型—————> 队列任务的执行方式 四种组合方式 1> 创建队列 2>用函数封装任务
栈 一个口 先进后出 队列 两个口 先进先出
可以在任务中打印 执行当前任务的 当前线程(CurrentThread)
主队列是一个串行队列 必须在主线程中执行 主队列 + 同步函数 在主线程中组合会死锁 如果是在子线程中组合 不会死锁
异步函数 + 串行队列 会新建一个线程
懒加载就是重写属性的get方法 GCD的一次执行代码不能放在懒加载中 GCD的一次性代码主要用在单例模式 一个程序内只会执行一次
延时执行代码的方法:
[self performSelector:@selector(delay) withObject:nil afterDelay:2]
[ NSTimer scheduledTimerWithTimeInterval ……..]
dispatch_after //可以控制在哪个队列中执行
栅栏函数:控制非全局并发队列(自己创建的并发队列)里面的任务的执行顺序 往并发队列里面添加一个栅栏任务 栅栏前的先执行 栅栏后的后执行
GCD快速迭代: 就是遍历 for循环实现的操作 是串行的 上一个for循环执行完才能执行这个for循环 快速迭代遍历是并发的 可以开新的线程 剪切电影的时候 替代for循环
同步串行有序 异步并发无序
重要发现: 同步函数是阻塞的 我执行了,后边的代码才能执行, 异步函数不是阻塞的 我没执行,后边的代码也能执行
用同步函数来添加任务,里面的任务执行不完 后面的代码都不会执行
用异步函数来添加任务,里面的任务执行不完 后面的代码也能执行
GCD就一句话 函数封装任务,然后添加任务到队列/队列组 添加任务到队列(新建队列,函数,然后添加到队列) 添加任务到队列组(新建队列,队列组,函数,然后添加到队列组)