美文网首页
RunLoop 02 - 应用(线程保活)

RunLoop 02 - 应用(线程保活)

作者: 石头89 | 来源:发表于2019-08-21 22:45 被阅读0次

    RunLoop 02 - 应用(线程保活)

    PermanentThread

    @interface PermanentThread : NSObject
    
    @property (readonly, getter=isExecuting) BOOL executing;
    @property (readonly, getter=isFinished) BOOL finished;
    
    - (void)executeTask:(void (^)(void))task;
    - (void)stop;
    
    @end
    
    @interface PermanentThread ()
    
    @property (nonatomic, strong) NSThread *thread;
    @property (nonatomic, assign, getter=isKeepRunning) BOOL keepRunning;
    
    @end
    
    @implementation PermanentThread
    
    - (void)dealloc {
        NSLog(@"%s", __func__);
        if (self.isExecuting) {
            [self stop];
        }
    }
    
    - (BOOL)isExecuting {
        return self.thread.isExecuting;
    }
    
    - (BOOL)isFinished {
        return self.thread.isFinished || self.thread.isCancelled;
    }
    
    - (instancetype)init {
        if (self = [super init]) {
            self.keepRunning = true;
            __weak typeof(self) weakSelf = self;
            self.thread = [[NSThread alloc] initWithBlock:^{
                NSLog(@"---- PermanentThread Begin ----");
    
                // ----------------- CFRunLoop -----------------
                // 1. 创建 Source、添加 Source
                CFRunLoopSourceContext context = {0};
                CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
                CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
                CFRelease(source);
    
                // 2. 启动 RunLoop,循环执行
                CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
    
                // ----------------- NSRunLoop -----------------
    //            // 1. 添加 Source
    //            [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
    //            // 2. 启动 RunLoop,循环执行
    //            while (weakSelf && weakSelf.isKeepRunning) {
    //                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    //            }
    
                NSLog(@"---- PermanentThread End ----");
            }];
            [self.thread start];
        }
        return self;
    }
    
    - (void)executeTask:(void (^)(void))task {
        if (self.isExecuting) {
            [self performSelector:@selector(__executeTask:) onThread:self.thread withObject:task waitUntilDone:NO];
        }
    }
    
    - (void)stop {
        if (self.isExecuting) {
            [self performSelector:@selector(__stopRunLoop) onThread:self.thread withObject:nil waitUntilDone:YES];
        }
    }
    
    - (void)__executeTask:(void (^)(void))task {
        task();
    }
    
    - (void)__stopRunLoop {
        self.keepRunning = NO;
        CFRunLoopStop(CFRunLoopGetCurrent());
    }
    
    @end
    

    PermanentThread 使用示例

    @interface ViewController ()
    
    @property (nonatomic, strong) PermanentThread *thread;
    
    @end
    
    @implementation ViewController
    
    - (void)dealloc {
        NSLog(@"%s", __func__);
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.thread = [[PermanentThread alloc] init];
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        [self.thread executeTask:^{
            NSLog(@"%@,执行任务。。。", [NSThread currentThread]);
        }];
    }
    
    - (IBAction)stopButtonClicked:(id)sender {
        [self.thread stop];
    }
    
    @end
    

    相关文章

      网友评论

          本文标题:RunLoop 02 - 应用(线程保活)

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