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,使用NSPort为runloop增加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];
}
- (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进行投诉反馈,一经查实,立即删除!