美文网首页
iOS:线程保活

iOS:线程保活

作者: 春暖花已开 | 来源:发表于2020-08-05 20:27 被阅读0次
    自定义子线程MZChildThread
    //MZChildThread.h
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface MZChildThread : NSObject
    
    ///在子线程中执行任务
    - (void)executeTask:(void(^)(void))task;
    
    ///停止并销毁线程
    - (void)stopThread;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    //MZChildThread.m
    #import "MZChildThread.h"
    
    #if DEBUG
    #ifndef MZPrivateThreadLog
    #define MZPrivateThreadLog(...) NSLog(__VA_ARGS__)
    #else
    #define MZPrivateThreadLog(...)
    #endif
    #endif
    
    #pragma mark - _MZPrivateThread
    @interface MZPrivateThread : NSThread
    
    @end
    
    @implementation MZPrivateThread
    
    - (void)dealloc {
        MZPrivateThreadLog(@"%s", __func__);
    }
    
    @end
    
    
    #pragma mark - MZChildThread
    
    @interface MZChildThread ()
    
    @property (nonatomic, strong) MZPrivateThread *thread;
    @property (nonatomic, assign) BOOL shouldStop;
    
    @end
    
    @implementation MZChildThread
    
    #pragma mark - public Methods
    
    - (instancetype)init {
        if (self = [super init]) {
    
            __weak typeof(self) weakSelf = self;
            self.shouldStop = NO;
    
            self.thread = [[MZPrivateThread alloc] initWithBlock:^{
                //将端口作为输入源添加到运行循环的指定模式
                [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
    
                while (weakSelf && !weakSelf.shouldStop) {
                    //相当于run,但又与run不同的是,可以自己控制退出时机
                    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
                }
    
                //当线程保活时,该打印将被阻塞
                MZPrivateThreadLog(@"===end===");
            }];
    
            //开启线程
            [self.thread start];
        }
        return self;
    }
    
    - (void)executeTask:(void (^)(void))task {
    
        if (!self.thread || !task) return;
    
        [self performSelector:@selector(p_executeTask:) onThread:self.thread withObject:task waitUntilDone:NO];
    }
    
    - (void)stopThread {
    
        if (!self.thread) return;
    
        //waitUntilDone为YES,表示执行完子线程代码后,才执行之后的代码
        [self performSelector:@selector(p_stopThread) onThread:self.thread withObject:nil waitUntilDone:YES];
    }
    
    
    #pragma mark - public Methods
    
    - (void)p_executeTask:(void (^)(void))task {
        task();
    }
    
    - (void)p_stopThread {
        self.shouldStop = YES;
    
        //停止当前线程(一定要在开启的子线程中关闭),之后会解除阻塞
        CFRunLoopStop(CFRunLoopGetCurrent());
        self.thread = nil;
    }
    
    - (void)dealloc {
        //在释放的时候,要关闭线程,防止占用资源
        [self stopThread];
        MZPrivateThreadLog(@"%s", __func__);
    }
    
    @end
    
    使用
    #import "DetailViewController.h"
    
    #import "MZChildThread.h"
    
    @interface DetailViewController ()
    
    @property (nonatomic, strong) MZChildThread *thread;
    
    @end
    
    @implementation DetailViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.thread = [[MZChildThread alloc] init];
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
        [self.thread executeTask:^{
            NSLog(@"执行任务在 - %@", [NSThread currentThread]);
        }];
    }
    
    - (IBAction)stop {
        [self.thread stopThread];
    }
    
    - (void)dealloc {
        NSLog(@"%s", __func__);
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:iOS:线程保活

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