美文网首页
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