美文网首页
『ios』根据runloop设计保活线程

『ios』根据runloop设计保活线程

作者: butterflyer | 来源:发表于2021-07-13 20:23 被阅读0次

为了避免频繁的创建线程,我们可以利用runloop来设计一个保活线程。
需要注意的点
run和runmode的区别
[NSRunLoop currentRunLoop] 调用run方法,永远都停不下来。
[NSRunLoop currentRunLoop] 调用runmode方法,会在一次循环之后停止。

子线程默认不会开启runloop
我们需要手动添加port来开启runloop

需要注意我们要设计的是一个子线程保活,当然关闭runloop的时候,也要关闭子线程的runloop

[self performSelector:@selector(__stop) onThread:self.innerThread withObject:nil waitUntilDone:YES]
我们需要注意waitUntilDone这个参数,当设置为YES的时候,会等待performSelector执行完,才会执行后面的。如果设为NO则不会等待。

保活线程的销毁时机,是在调用dealloc的时候先进行停止在销毁。我们需要注意,在thread销毁过程中,while函数还在执行,要判断self是否还存在,防止直接调用self.stop造成的野指针错误

#import <Foundation/Foundation.h>

typedef void (^XHKeepAliveThreadTask)(void);

@interface XHKeepAliveThread : NSObject

/**
 开启线程
 */
//- (void)run;

/**
 在当前子线程执行一个任务
 */
- (void)executeTask:(XHKeepAliveThreadTask)task;

/**
 结束线程
 */
- (void)stop;

@end
#import "XHKeepAliveThread.h"

@interface XHThread : NSThread
@end
@implementation XHThread
- (void)dealloc
{
    NSLog(@"%s", __func__);
}
@end


@interface XHKeepAliveThread()
@property (strong, nonatomic) XHThread *innerThread;
@property (assign, nonatomic, getter=isStopped) BOOL stopped;
@end

@implementation XHKeepAliveThread
#pragma mark - public methods
- (instancetype)init
{
    if (self = [super init]) {
        self.stopped = NO;
        
        __weak typeof(self) weakSelf = self;
        
        self.innerThread = [[XHThread alloc] initWithBlock:^{
            [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
            
            while (weakSelf && !weakSelf.isStopped) {
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            }
        }];
        
        [self.innerThread start];
    }
    return self;
}

//- (void)run
//{
//    if (!self.innerThread) return;
//
//    [self.innerThread start];
//}

- (void)executeTask:(XHKeepAliveThreadTask)task
{
    if (!self.innerThread || !task) return;
    
    [self performSelector:@selector(__executeTask:) onThread:self.innerThread withObject:task waitUntilDone:NO];
}

- (void)stop
{
    if (!self.innerThread) return;
    
    [self performSelector:@selector(__stop) onThread:self.innerThread withObject:nil waitUntilDone:YES];
}

- (void)dealloc
{
    NSLog(@"%s", __func__);
    
    [self stop];
}

#pragma mark - private methods
- (void)__stop
{
    self.stopped = YES;
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.innerThread = nil;
}

- (void)__executeTask:(XHKeepAliveThreadTask)task
{
    task();
}

@end

相关文章

  • iOS底层原理——浅谈RunLoop

    RunLoop应用:线程保活 线程保活、控制销毁 iOS-浅谈RunLoop8iOS底层原理总结 - RunLoo...

  • 『ios』根据runloop设计保活线程

    为了避免频繁的创建线程,我们可以利用runloop来设计一个保活线程。需要注意的点run和runmode的区别[N...

  • iOS Runloop的理解与使用

    Runloop的概念 Runloop的存在主要就是为了线程保活,线程保活是为了线程能够及时的处理事件,不会在其执行...

  • iOS Runloop 线程保活及坑

    iOS Runloop 线程保活及坑 上面的代码, Thread 这个类继承自 NSThread ,然后重写了 d...

  • iOS笔记-runloop

    runloop可以做什么? 处理crash 保持线程存活(线程保活) 监测、优化卡顿 线程和runloop有什么关...

  • RunLoop 02 - 应用(线程保活)

    RunLoop 02 - 应用(线程保活) PermanentThread PermanentThread 使用示例

  • RunLoop学习笔记

    参考深入理解RunLoop深入研究 Runloop 与线程保活RunLoop分享by孙源 RunLoop的概念 R...

  • Runloop源码解析:运行逻辑

    Runloop应用: Timer失效问题; 线程保活; Runloop的运行逻辑: 入口函数 通知Observer...

  • 10.3 runloop 的实际应用

    runloop实际中的应用 控制线程生命周期(线程保活)、崩溃的起死回生 runloop和performselec...

  • iOS总结篇-RunLoop

    RunLoop是什么? RunLoop是一个事件循环,让线程休眠和线程保活成为了可能,线程休眠可以节省CPU资源;...

网友评论

      本文标题:『ios』根据runloop设计保活线程

      本文链接:https://www.haomeiwen.com/subject/yywspltx.html