GCD
多线程
NSTheard :alloc init 方法创建线程 。
start 方法启动线程 。然后系统会管理线程的生命 。当对应的方法执行完毕之后 ,线程会自动销毁 。
[NSTheard isMainTheard] 会监测包含的方法是不是在主线程中。
performSelectorInBackground:(SEL) withobject:(id)
是隐式创建线程 。
主线程阻塞 :
preformSelectorInMainTheard withObject waitUnitDone:(BOOL)
最后的bool值就是 ,是否要在执行完对应的方法之前 ,阻塞主线程 。
线程的状态
start 以后,线程就是Runnable状态。 放到了cpu调度池中等待cpu调用 。当cpu调度了这个线程以后,就是运行状态running 。然后执行一段时间,cpu切换了别的线程 。就又回到等待就绪状态Runnable
当调用了sleep/等待同步锁操作后 ,线程就在阻塞状态blocked
阻塞线程
+(void)sleepUnitilDate:(NSDate *)date
+(void)sleepForTimeInterval:(NSTimeInterval*)ti
强制退出线程
+(void)exit
多线程的安全问题 :抢占资源 线程锁
互斥锁 :@synchornized(锁对象)
注意:锁对象要是同一个 ,才能对各个线程纪录正确的锁状态 。
加锁了 ,就会造成线程同步 。相当于一个同步线程队列 。
原子和非原子
原子:atomic 默认就为setter 方法加锁 。默认就是线程安全的 。注意:属性默认就是atomic
线程间通信
-(void)performSelectorOnMainThread:(SEL) withobject :(id) waitUnitilDone:(BOOL);
-(void)performSelector:(SEL) onThread:(NSThread) withObject:(id) waitUntilDone:(BOOL)
GCD
使用步骤:
- 定制任务:确定子线程需要做什么事情
- 将任务添加到队列中:GCD会自动将队列中的任务取出,放到对应的线程中去执行。
- 任务的取出遵循FIFO原则:先进先出 ,后进后出 。
GCD的两个创建任务的函数 :
dispatch_async(dispatch_queue_t queue, ^(void)block) :异步 可以开启新的线程
dispatch_sync(dispatch_queue_t queue, ^(void)block) :同步 意思是和外边的代码在同一个线程中 。不具备开启新线程的能力
队列类型
- 并发队列(Concurrent dispatch queue)
- 串行队列 (Serial dispatch queue)
- 创建一个并发队列:
类型包括两种 :dispatch_queue_t queue = dispatch_queue_create(名字 ,队列类型)
- 1 DISPATCH_QUEUE_CONCURRENT (并发)
- 2DISPATCH_QUEUE_SERIAL (串行)
创建好了,只要把任务加入队列中就可以了 。创建线程,开启,销毁等等都不需要管。
系统默认是提供了全局的并发队列 。不需要手动创建 。
dispatch_get_global_queue(优先级 ,一个以后需要的参数 现在默认填0)
优先级 :DISPATCH_QUEUE_PRIORITY_(BACKGROUD(最低)/DEFAULT/HIGH/LOW)
主队列:系统提供的串行队列 放到主队列中的任务都会在主线程中执行 。dispatch_get_main_queue()
在这个时候 ,异步函数也不会创建新的线程 ,只能在主线程中执行 。
异步+串行队列 。
不管添加了几个任务 。都只会创建一个子线程 ,然后串行,一个一个的挨个完成 。
同步函数+主队列 。
会卡死。 注意:同步函数 ,马上就需要执行 ,并不会等队列所在的函数执行完再执行 。 异步函数,会等外边的大函数先执行完,再执行队列中的异步任务 。
GCD函数--阻隔函数
dispatch_berrier_async()
在异步的并发队列中 ,会先执行他前面的任务 ,然后执行他本身的任务 ,最后才执行他后边的任务 。(注意 ,在系统的全局队列中不管用)只能自己创建并发队列 。
宏定义
当有多行的时候,需要换行 ,用\连接 。
当要在后边拼接文字的时候 ##