RunLoop

作者: MoonBall | 来源:发表于2015-09-05 12:04 被阅读318次

    自己的一些测试结论:

    Note:对于 performSelector: 操作,如果没有 afterDelay: 则会在当前线程立即执行;但是如果加了 afterDelay:,则会被添加到相应线程的 RunLoop 中执行。对于 performSelector: 如果有 onThread:,那么该处理也会被添加到指定线程的 RunLoop 中去执行。对于非主线程的其他线程,默认下是没有 RunLoop 的,使用 [NSRunLoop currentRunLoop] 会在当前线程创建 RunLoop,但该 RunLoop 需要手动 run 起来。如果使用 NSTimer 或执行 performSelector: 将对应任务加入到线程的 RunLoop 中,一定要启动对应线程的 RunLoop,即 [[NSRunLoop currentRunLoop] run]

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [self performSelector:@selector(printYogy) withObject:nil];
        NSLog(@"_missing");
    }
    - (void)printYogy {
        NSLog(@"yogy....");
    }
    // 输出为:
    // yogy....
    // _missing
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        [self performSelector:@selector(printYogy) withObject:nil  :0];
        NSLog(@"_missing");
    }
    - (void)printYogy {
        NSLog(@"yogy....");
    }
    // 输出为:
    // _missing
    // yogy....
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(printYogy) object:nil];
        [thread start];
        [self performSelector:@selector(printHaHa) onThread:thread withObject:nil waitUntilDone:NO];
        
        NSLog(@"_missing");
    }
    - (void)printYogy {
        // 如果注释下面两行代码,就不会输出 Haha.... 但会输出 yogy... 说明了,
        // performSelector: onThread: 是把操作加到指定线程的 RunLoop 中。且由于 RunLoop 就是在一个线程中执行的,
        // 所以当一个线程的 RunLoop 如果 run 起来,当前线程就进入 run,而等待它返回。(目前它一直都没有返回)
        [[NSRunLoop currentRunLoop] addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] run];
        NSLog(@"yogy....");
    }
    - (void)printHaHa {
        NSLog(@"Haha....");
    }
    // 输出为:
    // Haha....
    // _missing
    

    Note:对于 Serial Dispatch Queue 使用 waitUntilDone:YES 同样有效。其实,performSelector: 操作都是相对于指定线程的 RunLoop 来说的,所以与 Dispatch Queue 没有任何联系。这里只是说明了:一个线程可以对自己使用 waitUntilDone:YES

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        dispatch_queue_t queue = dispatch_get_main_queue();
        dispatch_async(queue, ^{
            NSLog(@"...queue");
            [self performSelector:@selector(printYogy)
                         onThread:[NSThread currentThread]
                       withObject:nil
                    waitUntilDone:YES];
            NSLog(@"_missing");
        });
        
        [NSThread sleepForTimeInterval:1.0];
        NSLog(@"...main");
    }
    
    - (void)printYogy {
        [NSThread sleepForTimeInterval:2.0];
        NSLog(@"yogy....");
    }
    // 输出为:
    // ...main
    // ...queue
    // yogy....
    // _missing
    

    参考资料:
    深入理解RunLoop
    RunLoop基础元素解析
    【iOS程序启动与运转】- RunLoop个人小结
    NSTimer和Runloop的关系

    相关文章

      网友评论

        本文标题:RunLoop

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