performSelector:withObject与performSelector:withObject:afterDelay的区别

#import "PerformSelectorAfterDelayVC.h"

@interface PerformSelectorAfterDelayVC ()

@end

@implementation PerformSelectorAfterDelayVC

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 方法一
//    // 当在子线程执行下面的代码的时候,发现
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    dispatch_async(globalQueue, ^{
        NSLog(@"1");
        [self performSelector:@selector(test) withObject:nil afterDelay:2.0];
//        [self performSelector:@selector(test) withObject:nil];

        NSLog(@"3");
        //        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    });
//
   
    // 方法二:
//    NSLog(@"1");
//    [self performSelector:@selector(test) withObject:nil afterDelay:3.0];
//    NSLog(@"3");
 
}

- (void)test
{
    NSLog(@"2");
}

@end

总结:

 /*
     - (id)performSelector:(SEL)sel {
     if (!sel) [self doesNotRecognizeSelector:sel];
     return ((id(*)(id, SEL))objc_msgSend)(self, sel);
     }
     
     - (id)performSelector:(SEL)sel withObject:(id)obj {
     if (!sel) [self doesNotRecognizeSelector:sel];
     return ((id(*)(id, SEL, id))objc_msgSend)(self, sel, obj);
     }
     
     说明performSelector:withObject是发送的objc_msgSend的消息,说明[self performSelector:@selector(test) withObject:nil];等价于[self test];但是
     如果换为performSelector:withObject:afterDelay:在子线程中就不执行了,但是如果放在主线程的话,performSelector:withObject:afterDelay:就可以执行,那是因为该方法是在NSRunLoop中定义的,说明afterDelay是跟runLoop有关的.参数afterDelay:说明该方法是将定时器添加到RunLoop中,比如几秒之后开始做事情的定时器放到RunLoop中,Runloop在唤响之后才会处理定时器.所以该代码有效的前提是,有RunLoop,在主线程中有Runloop所以这句代码好使,但是如果在子线程默认情况下,没有runloop,意味着定时器无法工作,除非在子线程中启动runloop之后定时器才可以工作.
     
     */

第二个关于RunLoop中线程的代码

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSThread *thread = [[NSThread  alloc]initWithBlock:^{
        NSLog(@"1");
        
//        [[NSRunLoop currentRunLoop]addPort:[[NSPort alloc]init] forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        NSLog(@"END");
    }];
    [thread start];
    
    [self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];
    
}

- (void)test
{
    NSLog(@"2");
    CFRunLoopStop(CFRunLoopGetCurrent());
}

发布了337 篇原创文章 · 获赞 25 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u012581760/article/details/88988776