ios初级 (线程与队列的关系,傻瓜学线程)
简介
对于许多面试题 会经常问一些比较简单问题 问线程 进程区别 或者线程与队列的到底有什么关系. 线程 和进程关系这里就不讲了比较简单
线程与队列的关系和区分

如图 一个程序只有一个主队列, 并且主队列是一个特殊的串行队列
所以说主队列是一个串行队列
绿图(饭堂模型) 并行队列 就是多条线程一起 执行任务没有顺序
如果把这个图看成一个进程的话 那么这个进程里一共开了四条线程.(一个主线程 三个子线程).
如何开线程
在ios里面一共有三种方式 开辟线程 1.NSThread 2.GCD 3.NSOPeration
第一种很少人会用 他是oc开线程的方法 因为有许多缺点 所以很少人会用(缺点:手动管理线程, 无法利用多核技术)
第二种 第三种 需要掌握 这里我们主要说说GCD 是如何开线程的
第三种NSOPeration 是对苹果公司 对GCD 的一个封装(掌握)
GCD 应用广泛
自动开线程 ,延迟操作,运用于单例的创建等.
GCD开线程
大家都听过异步 和同步吧 其实异步和同步 就是用GCD 来写的
大家记住一件事
dispatch_async(dispatch_get_main_queue(), ^{ });异步里参数除非是dispatch_get_main_queue() 这个主队列 其余的包括 全局队列(并行队列) 和串行队列放入这个异步 作为参数时 他们都会自动创建线程
那么在异步添加到 并行队列(全局队列)与串行队列 都会自动开线程那么他们有什么区别吗?
全局队列是什么 他是一个系统自带的并行队列 所以大家以后不用创建并行队列 直接用.
串行队列 需要手动创建 程序里 已经有了一个特殊的串行队列dispatch_get_main_queue()(主队列)主队列比较特殊 异步加入主线程 这个异步不会开启线程 . 会在主线程执行
但是自定义创建的串行队列 就不一样了
/**
* async -- 并发队列(最常用)
* 会不会创建线程:会,一般同时开多条
* 任务的执行方式:并发执行
*/
- (void)asyncGlobalQueue
{
// 获得全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 将 任务 添加 全局队列 中去 异步 执行
dispatch_async(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
}
/**
* async -- 串行队列(有时候用)
* 会不会创建线程:会,一般只开1条线程
* 任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务)
*/
- (void)asyncSerialQueue
{
// 1.创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL);
// 2.将任务添加到串行队列中 异步 执行
dispatch_async(queue, ^{
NSLog(@"-----下载图片1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下载图片5---%@", [NSThread currentThread]);
});
把这几行代码粘到你工程中 你就明白了(打印当前线程) 如代码注释所示 异步加入串行队列 无论你写多少异步 加入者个串行队列 他只会开一条线程.
而异步加入全局队列 你有几个异步那么他开几个线程(最好不要超过5个).
线程的锁死
简单的锁死 有些人 会在主线程中 执行dispatch_sync(dispatch_get_main_queue(), ^{ });
这一行的代码 这样会造成锁死
原因
写了这句话他会加入主线程队列里 等待主线程完成 才回返回block里面的内容.但是当程序运行到这行代码 由于主线程没有完成 block 不会有返回.并且也不会跳过这行代码 所以就造成了死锁现象.
主队列和主线程的区别
代码描述[NSOperationQueue mainQueue]主队列 [NSThread mainThread]主线程
二者关系 主队列里 必须有一个主线程 主队列里可以在加线程
同步加入全局队列要注意的是
dispatch_sync 在全局队列是可以写的 等主队列执行完了 它再执行就是了 没什么大不了