最近看了一些关于常驻线程的文章,发现了一些问题,写此文章记录一下,如果有写的不对的地方,欢迎大神指出...
常驻线程 : 要求子线程一直保活状态,随时待命,指定任务在这个长期保活的线程上执行
废话不多说了,直接上代码
@property (nonatomic, strong) NSThread *thread;
@property (nonatomic, assign) BOOL runloopLife;
- (void)viewDidLoad {
[super viewDidLoad];
self.runloopLife = YES;
self.thread = [[NSThread alloc]initWithTarget:self selector:@selector(test) object:nil];
[self.thread start];
}
- (void)test{
//添加Port 实时监听
[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
//添加runloop
[[NSRunLoop currentRunLoop]run];
}
- (void)run{
NSLog(@"%@ %s",[NSThread currentThread],__func__);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self performSelector:@selector(run) onThread:self.thread withObject:nil waitUntilDone:NO];
}
控制台输出:
![](https://img.haomeiwen.com/i1707826/f85bd3c0c5f1a2d2.png)
这样就说明,
self.thread
是保活了的,但是还是有问题的,如果现在控制器被pop的时候,控制器并没有销毁,说明是有内存泄漏的,修改代码如下:
- (void)test{
[[NSRunLoop currentRunLoop]addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
while (self.runloopLife) {
[[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.3]];
}
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.runloopLife = NO;
}
- (BOOL)runMode:(NSRunLoopMode)mode beforeDate:(NSDate *)limitDate;
这个方法官方是这样说的:如果没有输入源连接到运行循环,此方法立即退出,并返回NO,否则,在处理第一个输入源或达到limitDate后返回,如果手动从运行循环中删除所有已知的输入源和定时器并不能保证运行循环会立即退出,如果运行循环运行并处理输入源或达到了指定的超时值,则为YES;否则,如果运行循环无法启动,则为NO
如果大家还有别的好的建议请留言,欢迎大家交流
网友评论