多线程三: NSThread 面试题

- (void)viewDidLoad {
   [super viewDidLoad];
   NSThread *thread = [[NSThread alloc] initWithBlock:^{
        NSLog(@"1");
    }];
    [thread start];
    
    [self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];
}

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

打印结果:
1
然后崩溃
错误信息是:
Terminating app due to uncaught exception ‘NSDestinationInvalidException’, reason: ‘*** -[ViewController performSelector:onThread:withObject:waitUntilDone:modes:]: target thread exited while waiting for the perform’


这是因为

  • test 方法是放在 thread 线程中执行的;
  • 当 程序执行到 [thread start] 方法时,initWithBlock 中的 内容已经执行完毕,thread 线程就销毁了。
  • 所以当 执行 test 方法时, 因 thread 线程已经被销毁。自然就崩溃了。

可以添加 runloop 来解决此问题。

    NSThread *thread = [[NSThread alloc] initWithBlock:^{
        NSLog(@"1");
        [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }];
    [thread start];
    
    [self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];

如果代码改成 后 执行 [thread start ] 会发生什么 ?

- (void)getNSThreadFirst {
    NSLog(@"123");
    NSThread *thread = [[NSThread alloc] initWithBlock:^{
        NSLog(@"1");
    }];
    
    NSLog(@"456");
    [self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:YES];
    
    NSLog(@"789");
    [thread start];
    
    NSLog(@"098");
}

执行结果:
在这里插入图片描述

这是因为 相互等待,因为 waitUntilDone = yes 。


把 waitUntilDone 改成 No.

- (void)getNSThreadFirst {
    NSLog(@"123");
    NSThread *thread = [[NSThread alloc] initWithBlock:^{
        NSLog(@"1");
    }];
    
    NSLog(@"456");
    [self performSelector:@selector(test) onThread:thread withObject:nil waitUntilDone:NO];
    
    NSLog(@"789");
    [thread start];
    
    NSLog(@"098");
}

执行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值