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
网友评论