美文网首页
关于NSTread的问题

关于NSTread的问题

作者: 宇轩Simid | 来源:发表于2017-04-06 14:50 被阅读0次

    对于多线程,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 还是会把子线程干掉的,也还有标记作用。

    相关文章

      网友评论

          本文标题:关于NSTread的问题

          本文链接:https://www.haomeiwen.com/subject/crfqattx.html