美文网首页
performSelector相关

performSelector相关

作者: 雷霸龙 | 来源:发表于2021-03-29 21:38 被阅读0次

    基础用法

    //在当前线程延迟1s执行,响应了OC语言的动态性:延迟到运行时才绑定方法
    [self performSelector:@selector(aaa) withObject:nil afterDelay:1];
    // 回到主线程,waitUntilDone:是否将该回调方法执行完再执行后面的代码
    // 如果为YES:就必须等回调方法执行完成之后才能执行后面的代码,说白了就是阻塞当前的线程
    // 如果是NO:就是不等回调方法结束,不会阻塞当前线程
    [self performSelectorOnMainThread:@selector(aaa) withObject:nil waitUntilDone:YES];
    // 开辟子线程
    [self performSelectorInBackground:@selector(aaa) withObject:nil];
    //在指定线程执行
    [self performSelector:@selector(aaa) onThread:[NSThread currentThread] withObject:nil waitUntilDone:YES];
    

    延迟执行

    [obj performSelector:@selector(play) withObject:@"雷霸龙" afterDelay:4.f];
    

    performSelector:withObject:afterDelay:其实就是在内部创建了一个NSTimer,然后会添加到当前线程的Runloop中。

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        [self performSelector:@selector(test) withObject:nil afterDelay:2];
        [[NSRunLoop currentRunLoop] run];
    });
    

    [[NSRunLoop currentRunLoop] run];必须放在后面,在子线程中两者的顺序必须是先执行performSelector延迟方法之后再执行run方法。因为run方法只是尝试想要开启当前线程中的runloop,但是如果该线程中并没有任何事件(source、timer、observer)的话,并不会成功的开启。

    在子线程中调用该performSelector延迟方法,会发现调用该延迟方法的子线程和test方法中执行的子线程是同一个,也就是说:对于该performSelector延迟方法而言,如果在主线程中调用,那么test方法也是在主线程中执行;如果是在子线程中调用,那么test也会在该子线程中执行。

    performSelector:withObject:如果没有带延迟时间的情况下,即使是放在子线程中,也能正常执行,不需要[[NSRunLoop currentRunLoop] run];,只是一个单纯的消息发送,和时间没有一点关系,所以不需要添加到子线程的Runloop中也能执行。

    如何在不使用GCD和NSOperation的情况下,实现异步线程?

    1、使用NSThread的三个方法:
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
    [NSThread detachNewThreadSelector:@selector(test) toTarget:self withObject:nil];
    [NSThread detachNewThreadWithBlock:^{
            NSLog(@"block中的线程 ---- %@",[NSThread currentThread]);
    }];
    
    2、performSelectorInBackground 后台执行
    [self performSelectorInBackground:@selector(test) withObject:nil];
    

    performSelector和直接调用方法的区别

    performSelector: withObject:是在iOS中的一种方法调用方式。他可以向一个对象传递任何消息,而不需要在编译的时候声明这些方法。所以这也是runtime的一种应用方式。

    所以performSelector和直接调用方法的区别就在与runtime。直接调用编译是会自动校验。如果方法不存在,那么直接调用在编译时候就能够发现,编译器会直接报错。

    但是使用performSelector的话一定是在运行时候才能发现,如果此方法不存在就会崩溃。所以如果使用performSelector的话他就会有个最佳伴侣- (BOOL)respondsToSelector:(SEL)aSelector;来在运行时判断对象是否响应此方法。

    相关文章

      网友评论

          本文标题:performSelector相关

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