iOS开发我们经常使用异步线程处理耗时任务,在一些场景中,如果频繁地创建和销毁线程的话,会带来额外的开销,所以有时需要线程保活。iOS中runloop事件循环,它可以持续等待处理用户交互和UI渲染,每一个线程都对应一个runloop。对于主线程来说,runloop默认开启的,而对于子线程来说,runloop默认关闭的。可以通过开启runloop来做线程保活。

这里有个线程保活的例子,在ViewController页面可见的时候创建一个线程并且保活,在页面消失的时候销毁线程,停止runloop页面可见和不可见的状态可能是频繁触发的,所以这里的线程保活仅仅是示例,在实际应用可以根据情况减少线程创建和销毁的次数。

在ViewController类中,增加NSTread类型属性,增加keepRunning代表线程的运行状态

@interface SecondViewController ()

@property (nonatomic, strong) NSThread *thread;
@property (nonatomic, assign) BOOL keepRunning;

@end

viewWillAppear中创建线程,使用[NSRunLoop currentRunLoop];获取当前runloop使用NSPortrunloop增加source以便runloop运行。runloop运行的时候必须使用-runMode:beforeDate:这个方法,只有这个方法运行的runloop可以停止的。-runUntilDate:和run方法运行的runloop可以停止,因为runUntilDate:方法运行runloop的时候,它会在循环持续调用-runMode:beforeDate:导致runloop无法使用stop方法停止运行。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.keepRunning = YES;
    __weak typeof(self) weakSelf = self;
    self.thread = [[NSThread alloc] initWithBlock:^{
        NSRunLoop *theRL = [NSRunLoop currentRunLoop];
        [theRL addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
        while (weakSelf.keepRunning){
            [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            NSLog(@"test");
        }
    }];
    [self.thread start];
}

viewWillDisappear中增加代码

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    [self performSelector:@selector(invalidateThread) onThread:self.thread withObject:nil waitUntilDone:YES];
}

- (void)invalidateThread
{
    self.keepRunning = NO;
    CFRunLoopRef rl = CFRunLoopGetCurrent();
    CFRunLoopStop(rl);
}

invalidateThread方法用于停止runloop,runloop终止后,线程也会释放。

原文地址:https://blog.csdn.net/u011608357/article/details/128163979

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_16379.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注