美文网首页
RunLoop入门

RunLoop入门

作者: melody5 | 来源:发表于2018-06-22 16:41 被阅读14次

我们的项目其实就是一个RunLoop,比如main函数的UIApplicationMain就是一个死循环函数,它在不停的询问是否有事件发生,比如我在main函数里这样写:

int main(int argc, char * argv[]) {
    @autoreleasepool {
        
        NSLog(@"%@",[NSThread currentThread]);
        //UIApplicationMain  死循环 -- Runloop循环
        int a = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        NSLog(@"来了没");
        return a;
    }
}
2018-06-21 17:10:56.622877+0800 001--Runloop1[752:290434] <NSThread: 0x1d0075280>{number = 1, name = main}

最后我只得到了第一次打印,证明程序在UIApplicationMain函数进入了死循环,所以没有走到我的第二次打印

1、RunLoop的作用

  1. 保住当前线程的生命
  2. 监听事件:触摸,网络,时钟

2、RunLoop的几种运行模式

    NSTimer * timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
    
    //timer添加到Runloop中!!
    //NSDefaultRunLoopMode    默认模式,如果UI有操作时,runloop会暂停
    //UITrackingRunLoopMode   UI模式,当UI上有滑动等操作时才会运行,否则暂停
    //NSRunLoopCommonModes    占位模式!!UI&&默认!,在前两种模式下都会运行

    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
- (void)timerMethod {
    
    NSLog(@"%@--跑起来!!",[NSThread currentThread]);
}

通过打印就可以看出他们的区别,自己验证一下吧,比如放一个scrollView,比较滑动和不滑动时几种模式的不同。

3、用RunLoop保住线程的生命

如果不想RunLoop受到UI操作的影响,我们可以把他放到子线程里去执行

    NSThread * thread = [[NSThread alloc] initWithBlock:^{
        NSTimer * timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0001]];
        NSLog(@"走起");
        
    }];
    
    [thread start];

但是这时候发现,只有“走起”被打印了,timer的timerMethod并没有执行,这是因为thread里的代码执行完之后thread就销毁了,我们自定义一个继承自NSThread的类,然后实现它的dealloc方法,可以发现它被销毁了

-(void)dealloc
{
    NSLog(@"线程挂了");
}
2018-06-21 18:03:53.979368+0800 001--Runloop1[767:305273] 走起
2018-06-21 18:03:53.979485+0800 001--Runloop1[767:305273] 线程挂了

到这个你可能会说,让控制器强引用它不就完了吗?
但是并不行,因为这样OC的对象被留住了,但是底层的线程还是被释放了,那怎么才能保住当前线程的生命呢?

答案是让线程有执行不完的任务!!!
    NSThread * thread = [[NSThread alloc] initWithBlock:^{
        NSTimer * timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        while (true) {
            [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0001]];
        }
        NSLog(@"走起");
        
    }];
    
    [thread start];

这时候发现,timerMethod方法被循环的调用起来了。我们把while的条件换成变量以后,运行过程把true变成f'alse,会发现RunLoop会停止,线程会销毁。

4、线程间的通讯

    NSThread * thread = [[NSThread alloc] initWithBlock:^{

        NSLog(@"-----%@",[NSThread currentThread]);
        [[NSRunLoop currentRunLoop] run];
    }];

    [thread start];

    [self performSelector:@selector(subThreadMethod) onThread:thread withObject:nil waitUntilDone:NO];
-(void)subThreadMethod{
    NSLog(@"subThreadMethod --- %@",[NSThread currentThread]);
}

在主线程给子线程添加执行代码。

相关文章

  • RunLoop汇总

    RunLoop 入门 看我就够了RunLoop 已入门?不来应用一下?ibireme的文章,关于RunLoop背后...

  • 底层原理探究(二)RunLoop

    转自: 老司机出品——源码解析之RunLoop详解入门使用: RunLoop入门 看我就够了孙源的Runloop视...

  • iOS复习之RunLoop

    1、事件循环2、用户态3、核心态4、常驻线程 主要 RunLoop文章:RunLoop入门 看我就够了iOS - ...

  • RunLoop入门

    什么是RunLoop Run Loop是一让线程能随时处理事件但不退出的机制。RunLoop 实际上是一个对象,这...

  • RunLoop入门

    我们的项目其实就是一个RunLoop,比如main函数的UIApplicationMain就是一个死循环函数,它在...

  • RunLoop入门

    之前在使用NSTimer时,遇到一个问题,NSTimer启动了,但是只会出现一次定时,之后就不起作用。问了同...

  • RunLoop入门学习补充资料

    本文是对iOS RunLoop入门小结一文的资料补充 1.RunLoop运行逻辑 以下是伪代码1,摘自https:...

  • RunLoop入门提高

    RunLoop是iOS和OSX开发中非常基础的一个概念.首先从CFRunLoop的源码入手,介绍RunLoop的概...

  • RunLoop已入门?不来应用一下?

    前言 对RunLoop还没有什么概念的同学请移步我的上一篇文章,传送门:RunLoop入门 看我就够了http:/...

  • RunLoop已入门?不来应用一下?

    前言 对RunLoop还没有什么概念的同学请移步我的上一篇文章,传送门:RunLoop入门 看我就够了 http:...

网友评论

      本文标题:RunLoop入门

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