RunLoop在main线程和自己创建的线程如何启动

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RunLoop在main线程和自己创建的线程如何启动相关的知识,希望对你有一定的参考价值。

本文介绍:这篇博客主要是描述的是RunLoop的启动机制。内容属于简单的系类的。

一、RunLoop和线程的关系

  每一个RunLoop对应一个线程。每一个线程都可以拥有一个RunLoop,这也就是说线程可以创建一个属于自己的Runloop,也可以不创建自己的RunLoop。这都是根据程序内部的需求来决定的。这里需要注意的是:你创建一个runLoop但是你还必须要手动的让其run。

二、main线程的RunLoop

  主线程是灌注这个程序的。而与main线程相对应的RunLoop是在程序启动的时候就开始生成。并且开始run。这些功能都是通过在这个函数实现的

UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

三、自己创建的线程的runloop

  你通过GDC创建了自己的一个线程。你想在自己的线程中使用runloop。那么你必须分两步走:

  (1)创建自己的runloop。(在这里说明一下,runloop是不能自己创建的。但是你可通过 getrunloop来获取,源码中是这样写的)

  (2)让runloop跑起来 CFRunLoopRun();

四、代码分析

  (1)在主线程中插入一个NSTimer源,你可以直接这些写:

- (void)viewDidLoad {
[NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(run) userInfo:nil repeats:NO];
}
-(void)run
{
    NSLog(@"run");
}

因为是在主线程中运行这个代码。所以NSTimer就自动的插入了主线程对应的RunLoop,而且你都不需要执行RunLoop Run的方法。

 (2)在自己创建的线程中执行这段代码

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
   
    dispatch_queue_t queue = dispatch_queue_create("zhaoyan", 0);
    dispatch_async(queue, ^{
        CFRunLoopRef runLoop = CFRunLoopGetCurrent();
        
       [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(run) userInfo:nil repeats:NO];

    });
}

-(void)run
{
    NSLog(@"run");
}

  这时候你会发现,在你的控制台中并不能输出字符串 run,这是因为你在名为“zhaoyan”线程中执行,但是这个线程中并没有创建runloop而且,runloop并没有run起来,所以不能执行,所以我们应该更改一下代码如下:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // 如果你在
    dispatch_queue_t queue = dispatch_queue_create("zhaoyan", 0);
    dispatch_async(queue, ^{
        CFRunLoopRef runLoop = CFRunLoopGetCurrent();
        
//        [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(run) userInfo:nil repeats:NO];
        NSTimer * timer =[[NSTimer alloc] initWithFireDate:[NSDate date] interval:0 target:self selector:@selector(run) userInfo:nil repeats:YES];
        CFRunLoopAddTimer(runLoop, (CFRunLoopTimerRef)timer, kCFRunLoopDefaultMode);
        CFRunLoopRun();
    });
    
    
    
}

-(void)run
{
    NSLog(@"run");
}

  这样我们开启了这个线程的runloop 和 把这个run起来。但是上面的代码中需要注意的是:[NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(run) userInfo:nil repeats:NO];注销了,因为这段代码是针对mian线程的。如果你这样写的话仍然不能打印字符串

  如果有什么不足希望大家留言!

以上是关于RunLoop在main线程和自己创建的线程如何启动的主要内容,如果未能解决你的问题,请参考以下文章

iOS 子线程用runloop保活的一个方案

iOS中RunLoop和线程的关系

runloop和线程有什么关系?

RunLoop

多线程RunLoop

RunLoop