您的位置:首页 > 移动开发 > IOS开发

iOS多线程小结

2016-04-27 13:51 411 查看
GCD

在GCD中加入了两个非常重要的概念 任务 和队列

任务:即操作,你想要干什么,说白了就是一段代码,在 GCD 中就是一个 Block,所以添加任务十分方便。任务有两种执行方式: 同步执行 和 异步执行,他们之间的区别是 是否会创建新的线程。

同步(sync)和异步(async)的区别是:会不会阻塞当前线程,直到block中的任务执行完毕.

如果是同步(sync)操作,它会阻塞当前线程并等待block中的任务执行完毕,之后当前的线程才会继续向下执行

如果是异步(async)操作,当前线程继续往下执行,不会阻塞当前线程。

队列:用于存放任务,一共有两种:串行队列和并行队列

串行队列:放在串行队列中的任务,GCD会按照FIFO(先进先出)的原则进行执行。取出来一个执行一个,执行完之后,再取出另一个,继续执行。这样一个一个的执行

并行队列:放在并行队列中的任务,也是按照FIFO取出任务,但是不同的是他取出来一个任务会放到一个线程,然后继续取一个放到别的线程。由于去的动作很快,可以忽略不接,看起来,所有的任务是一块执行的。需要注意的是,GCD会根据系统资源控制并行的数量,如果任务很多,并不会让所有的任务一块执行。

创建队列

主队列:这是一个特殊的串行队列。 主队列的作用主要是用来显示\刷新UI,处理UI事件(比如:点击、滚动、拖拽)。任何的刷新UI的操作都放在主队列,其他的耗时操作都放在其他队列

dispatch_queue_t  queue = dispacth_get_main_queue();


自己创建的队列:自己创建的队列可以使串行的队列也可以是并行的队列。第一个参数是一个标示符,用于 DEBUG 的时候标识唯一的队列,可以为空。第二个参数用来标示创建的队列是串行的还是并行的。传入DISPATH_QUEUE-SERIAL或者NULL标示串行的,传入DISPATH_QUEUE_CONCURRENT标示创建并行队列

//创建串行队列
dispatch_queue_t queue = dispatch_queue_creat("tk.bourne.testQueue",NULL);
dispatch_queue_t queues = dispatch_queue_creat("tk.bourne.testQueue",DISPATCH_QUEUE_SERIAL);
//创建并行队列
dispatch_queue_t queuec = dispatch_queue_creat("tk.bourne.testQueue",DISPATCH_QUEUE_CONCURRENT);


全局并发队列:系统提供的一个并发队列

我们通常不会重新创建一个并发队列而是使用dispatch_get_golbal_queue() 取得一个全局的并发队列(如果有多个并发队列可以自己使用dispatch_queue_creat来创建)

dispatch_queue_t  queue = dispatch_get_global_queue("DISPATCH_QUEUE_PRIORITY_DEFAULT",0);


1、iOS多线程有哪些方式,分别讲讲

有三种,NSThread NSOperation GCD

NSThread 是轻量级的多线程开发,使用起来不复杂,就是需要自己管理线程的生命周期

NSoperation 只要将NSOperation放到NSOPerationQueue这个队列中线程就会依次启动,NSOPerationQueue 负责管理、执行所有的NSOperation。在这个过程中可以方便的控制线程的总数和线程之间的依赖关系 (面向对象)

GCD 是基于C语言的一套多线程开发机制,是这三种中抽象层次最高,使用起来最简单的。(面向过程)

2、手写GCD那几个常用的多线程(子线程异步,一次执行,延后执行,异步后notify汇总)

子线程异步

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{

})

一次执行

static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{

});


延后执行

dispatch_after(dispatch_time_t when ,dispatch_queue_t queue ,^(void)block)

dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW,(int64-t)(1.0*NSEC_PER_SEC));//when 时间,从现在开始经过多少纳秒
viod(^task)() = ^{
//延迟执行的代码
}
//经过多少纳秒,有主队列调度任务异步执行
dispatch(when,dispatch_get_main_queue(),task);


3手写单例

static id _instance;

+(instancetype)sharedTool{
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
_instance = [[Tool alloc] init];
});
return _instance;
}


4 单核CPU下多线程为何也能提高效率

单核CPU下的多线程其实是假的,因为在同一时间处理器只能处理一个逻辑,只不过线程之间切换的比较快。

在单线程中运用多线程防止了阻塞,如果使用单线程,如果某个程序阻塞了线程后面的线程则难以执行了。例如:远程读取某个数据,对端迟迟没有返回数据,又没有设置超时时间,那么你的程序在数据返回之前就停止了运行。

而多线程就防止了这个问题,多条线程同时执行,哪怕一条线程的代码数据读取阻塞,也不影响其他任务的执行

9 原子核非原子属性

atomic :原子属性,为setter方法加锁 线程安全,需要消耗大量的资源

nonatomic:非原子性,不会给setter方法加锁 线程不全。

@property (assign,atomic) int age;
-(void)setAge:(int)age
{
@synchronized (self){
_age = age;
}
}


互斥锁的使用格式

@synchronized(锁对象){//需要锁定的代码}

附带:调试技巧1 打印视图层次

po [self.view recursiveDescription];


2 、临时刷新界面UI

命令行
e ((UIButton *)sender).backgroundColor = [UIColor redColor]

(UICachedDeviceRGBColor *) $41 = 0x00007fdd10715b00

e (void)[CATraction flush]


参考地址:标哥技术博客
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: