关于NSTread的问题

对于多线程,NSTread是很常用的一种,他有三种方法:

  1. init... 方法 (initWithTarget.... / initWithNewBlock),当然也可以继承NSTread创建子类写main()方法,然后init 再start。苹果不建议直接调用main方法启动。
  2. 静态方法 也就是类方法 (detachNewThreadSelector: / detachNewThreadWithBlock:)这两个方法。
  3. NSObject 方法 (performSelectorInBackground) 这个方法简单实用,有很多种。

以上这三种方法。
相对于2、3方法,1方法有些累赘,需要创建对象并进行调用启动方法。但是他也有他的好处,可以根据对象来设置不同的属性啊,属性,性。。。。对就是这个。

比如:

  1. 可以设置线程的名字,方便test的时候查看哪个线程出现问题。

  2. 设置优先级,让多个线程有个顺序,这个顺序不是串行执行,是并行执行,只不过优先级高的先开始。再开始执行的时候肯定是优先级高的会先开始执行,然后并行执行另一个子线程,交替执行,在执行的过程中 优先级高的先执行,优先级低的后执行 也不是绝对的,只不过优先级高的先执行的概率大。但是开始的时候肯定是优先级高的先执行。

  3. 标记cancel 判断是否活跃 判断是否完成 And so on......

So......问题也就出在 cancel 方法上。我查阅网上资料,和之前的认知,cancel 只是对线程做一个标记而已,并不会真正的阻塞取消该线程。
但是我今天试了试却发现了问题,让我不知道怎么解释。

上图吧


纠结1.png

在调用start方法后立刻掉cancel方法后 打印出来的信息。说明cancel方法已经阻止了子线程的执行。

纠结2.png

在调用start和cancel 方法中间随便写了一个NSLog,这个子线程就会被执行起来,从图上看,虽然都是出于以取消的标记,可是 图1 和 图2的状态完全不一样。

我的猜想:
都是在主线程中开始创建并执行、取消的。可能在start和cancel方法之间的Log会浪费一些时间,而这些时间恰恰却让这个子线程开始了执行,而开始了以后cancel就无法阻塞取消执行。
那么反过来他们之间没有其他代码,主线程按照顺序执行下来速度相当快,在子线程还在待启动中就已经被标记取消,这样可能导致子线程取消。

下面认证:

认证1.png

我的猜想是打印log浪费了时间。那么我们换个其他的,不打印log,加一些其他的代码。看图说话。 感觉我的猜想是对的!

认证2.png

不难看出,通过和 纠结1图 的对比 子线程启动是需要时间的,而且这个过程也感觉不是超级快吧~~两个log的时间就给耽误了。
所以说主线程还没来得及 执行cancel方法 子线程已经就开始执行了。

总结:

  1. 子线程在已经启动起来的状态下,调用cancel只是起到了标记的作用。
  2. 子线程在还没有启动起来的状态下,瞬间调用cancel 还是会把子线程干掉的,也还有标记作用。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容