首页 > 解决方案 > 如何“可视化”(观察)iOS 中退出的线程?

问题描述

在学习线程和运行循环时,我注意到一些文章说:“通常,线程一旦完成工作就退出。” 所以有时有必要使用NSRunloop.

问题是我如何证明“一旦完成工作就退出”这句话?我这样编码

- (void)doSomethingOnThread {
//    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//        NSLog(@"I'm on thread %@", [NSThread currentThread]);
//    });

    NSThread *thread1 = [[NSThread alloc] initWithBlock:^{
        NSLog(@"I'm on thread %@", [NSThread currentThread]);
    }];
    thread1.name = @"thread1";
    [thread1 start];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadExitHandler:) name:NSThreadWillExitNotification object:nil];
}

- (void)threadExitHandler:(NSNotification *)noti {
    NSLog(@"Thread will exit: %@", noti);
}

好吧,通知处理程序没有被调用。

所以,[1]:如何证明线程退出?[2]:什么样的线程会这样?(我知道主线程永远不会退出,那么其他线程呢?GCD线程,例如?)

标签: iosmultithreadingrunloop

解决方案


如果你想可视化它,我可能会使用调试器。例如,我在NSThread子类中设置了一个断点,我看到 Xcode 左侧面板中列出的线程:

在此处输入图像描述

但是,如果我在方法完成后一秒触发了另一个断点main,我会看到相关的“线程将退出”消息并且我的线程不再存在:

在此处输入图像描述

或者,您可以在子类的方法中添加一条NSLog语句,这也将展示它的释放。或者在调试内存对象图中查找子类。deallocNSThread


好吧,通知处理程序没有被调用。

我建议您NSThreadWillExitNotification在开始线程之前添加您的观察者。现在你在这个线程的开始和退出与观察者的添加之间有一个竞争条件。FWIW,我确实看到了“线程将退出”消息。

不相关,虽然学习线程和运行循环很好,但现在它几乎没有实际用途。掌握 GCD 可能更有用,它可以让我们摆脱线程的杂草,并提供性能优化和更丰富的 API 来编写健壮的多线程代码。


关于 GCD 是否创建持久线程,答案是肯定的,但是我们从这个细节中抽象出来了。但是 GCD 的性能优化之一是它为我们管理了一个线程“池”,而不是不断地启动新线程并为每个分派的代码块不断地销毁它们。

您可能想观看 WWDC 2016 的Concurrent Programming With GCD in Swift 3。它遍历队列、线程和运行循环之间的关系。


推荐阅读