ios多线程开发注意点一

之前一直在纠结于队列 和线程关系,实际上在ios 开发中,这二者之间的关系相当微妙,除了一个特殊情况(主队列和主线程的关系),它二者之间是相互独立的,其实只要记住一个要点就可以了,主队列是一个特殊的队列,首先,它是一个串行队列,其次,它自始至终占用一个特殊的线程--主线程,而主线程,自始至终仅被主队列占用,其他任何队列,不管并行还是串行,都不能占用主线程,除去这个奇葩之外,任意队列不管是系统的还是自建的,不管是串行还是并行的,所有跑在这些队列上的线程都是子线程,都不能用来刷新ui,一定要务必牢记这一点。

关于dispatch_async 这个大家用的最多,实际上,一些专业晦涩难懂的术语,对于这个函数的解释,感觉越描越黑,只需要举个例子就好了,只要涉及到dispatch_async  我们知道这个函数有个参数需要传入一个队列,那么既然用这个函数,必然涉及到队列。没有队列的参与,这个函数也就不能调用

队列我就不再过多解释了,现在只把队列比作一个人,dispatch_async函数的作用是:把一个“任务”(就是dispatch_async 后面的block块)异步的提交给一个队列,刚才讲了,队列就是一个人,所以现在我们知道了,dispatch_async 的作用就是把一个任务(block)块提交给一个人,让他去执行,问题来了。谁把这个任务提交给了这个人?很多人忽略了这个问题,这个提交的主动方很少有人关注,但是往往这个主动方才是你程序能不能正常跑不产生死锁的关键!

一个任务被异步提交给了一个人,首先有一个任务,其次是异步,第三是给了一个人(目标队列),那到底谁是主动方?其实很简单。。你只需要看你代码执行dispatch_async之前,是跑在那个队列的,就可以确定谁是主动方。。

比如我这段代码在viewdidload 种执行,那必然是主队列是发起方,异步的本质是不用等,比如我是主队列,你是目标队列。我现在把任务异步提交给你执行, 这时候你会发现,不等你把任务执行完毕,我就去干别的了。至于你执行完毕之后会不会告诉我,我不关心,你可以告诉我(通过block回调,或者叫做函数指针回调),也可以不告诉我(什么也不做)这是后话

总之,我把任务交给你之后,我不会做任何等待,就忙其他事情去了,这样我就不会因为等待你执行完任务而去等待,造成我没有时间去处理其他事情。这是异步的本质 

关于dispatch_sync 同步函数同样有两个参数,一个是目标队列(也就是你),一个是任务块的block。同样的发起方需要看 dispatch_sync的上下文环境,比如这个发起方同样是我。。 我同步的把任务交给你执行,这时候我什么也不干,等着你把任务执行完毕,然后你告诉我结果之后我再去干其他的。这是同步的本质。

假如你现在执行这个任务非常耗时,那我就要等你很久,又假如我就是主队列,那么我等你的这段时间,我什么也干不了,包括响应ui 
这时候页面就会卡住,但请注意这不是死锁,这仅仅是被卡住一会而已,等你把任务执行完,我就可以回去响应我的ui。

是在主线程刷新的ui 不是主队列,主队列都知道是个串行队列,但是相比一般的串行队列,它有一点非常特殊,就是自始至终,主队列的任务都只能用主线程去跑,其他串行队列则没这个限制

你可以尝试把ui刷新的任务放到任意其他串行/并行队列,然后调用主线程去执行,你会发现即使不是在主队列的情况下,ui 刷新不会有什么不同

还有一点,涉及到队列,必然是调度队列,对应的,不可能是分发队列,cpu调度线程来执行队列任务,所以说如果用队列编程,线程的调度权归操作系统所有,除了主队队列这个特里之外,你不可能知道在某个时间段 的某个队列中到底是那个线程再跑

猜你喜欢

转载自blog.csdn.net/wocaoqwerty/article/details/85243497