美文网首页
深入理解 [[NSRunLoop currentRunLoop]

深入理解 [[NSRunLoop currentRunLoop]

作者: AlwaysBlue | 来源:发表于2022-07-06 15:21 被阅读0次

    最近在看线程保活,发现了这个函数无法理解,根本原因还是这个函数的苹果文档没有深入理解,然后没有多做尝试。

    先说结论,再说过程。
    结论:1)runMode:beforeDate只是执行一次runloop循环,处理完第一次input source内容,就会结束该runloop。注:第一次的input source内容要有活干,才算第一次。2)timer不能算input source,比较特殊,文档里有说明,你会发现timer能正常运作。直到第一次input source出现才会停止runloop


    该函数对应的苹果文档:

    Demo1:为了验证run是启动一直跑,常驻。

    thread中开启监听,加入port,执行run 用户点击屏幕操作,会怎么执行

    启动后,为了启动runloop而加入的port没活干,直接发出32休眠通知。
    用户点击屏幕,runloop开始处理source0

    每次用户点击,都会进入一次runloop循环,但是直接是到达退出runloop状态,然后紧接着再进入。run的本质是不断执行runMode:。

    Demo2:为了验证runMode只运行一次
    其余不变,将[[NSRunLoop currentRunLoop] run];
    改为[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

    启动和run效果一样,但是runMode的文档是 “it returns after either the first input source is processed or limitDate is reached“。处理第一次的input source后就会返回,那么port也算第一次,但是是个没有任务的第一次(后面会做个实验,加入的是有任务的第一次,在看点击屏幕是否还会触发)提前结论:根据实验,应该是需要“有活干的第一次”才会停下来runloop。
    紧接着点击屏幕:

    执行完一次source0点击屏幕,runloop就结束了。
    再次点击,会出现崩溃。该线程已经结束,不再执行任务。报错是EXC_BAD_ACCESS。本质就是该块内存已经不能再执行所发出的指令了。

    延伸:如果把 [self performSelector:@selector(tttt) onThread:self.testThread withObject:nil waitUntilDone:YES];换成
     [self performSelector:@selector(tttt) onThread:self.testThread withObject:nil waitUntilDone:NO];就不会崩溃。
    YES的含义是一直等到执行完毕再往下执行;NO的含义是不用等执行完毕继续往下执行。

    Demo3:也是为了验证runloop只跑一次循环

    两个performSelector...waitUntilDone:NO都执行了。

    一个performSelector...waitUntilDone:YES;一个performSelector...waitUntilDone:NO,只执行第一句,因为要等第一个执行完,执行完runloop一次循环就结束了。不再执行第二个input source了。当然,此处再点击一次就是崩溃。因为perform到一个已经结束的线程上了。

    Demo4:runMode只执行一次,第一次加入的任务有活干,再点击就无反应了。

    如果在runMode前加入performSelector...waitUntilDone:NO,则是在runloop中执行

    如果在runMode前加入performSelector...waitUntilDone:YES,则执行完再往下走,相当于runloop中是空内容,无法启动runloop。perform的任务是没有在runloop中执行的。

    Demo5:在runloop中加入timer,timer比较特殊

    关于timer的小知识点:
    scheduledTimerWithTimeInterval生成的timer = timerWithTimeInterval+[NSRunLoop currentRunLoop] addTimer...]生成的timer。

    runMode方法根据文档:

    timer会在等待这个方法返回时,触发很多次。不被认为是一种input source。
    最后,简单提一嘴通过runloop检测卡顿原理:2和64是检测卡顿状态,根据状态的变化间隔。后面再细聊~

    相关文章

      网友评论

          本文标题:深入理解 [[NSRunLoop currentRunLoop]

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