Runloop 之 控制线程的生命周期(线程保活,常驻线程)

2020-03-06  本文已影响0人  有梦想的狼
  1. 创建一个控制线程的对象PermenantThread,并在其中申明相应的方法
typedef void (^PermenantThreadTask)(void);

@interface PermenantThread : NSObject
/**
 在当前子线程执行一个任务
 */
- (void)executeTask:(PermenantThreadTask)task;

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

@end
  1. 在.m文件中添加相应的代码:
/** MJThread **/
@interface MJThread : NSThread
@end
@implementation MJThread
- (void)dealloc
{
    NSLog(@"%s", __func__);
}
@end

/** PermenantThread **/
@interface PermenantThread()
@property (strong, nonatomic) MJThread *innerThread;
@end

@implementation PermenantThread
#pragma mark - public methods
- (instancetype)init
{
    if (self = [super init]) {
        self.innerThread = [[MJThread alloc] initWithBlock:^{
            NSLog(@"begin----");
            
         //--------C语言运行RunLoop-----------
        //创建上下文(需要初始化一下结构体,因为auto局部变量,如果不初始化,会造成乱码的情况)
        CFRunLoopSourceContext context = {0};
        
        //创建source
        CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
        
        //往RunLoop中添加source
        //因为Mode中没有任何Source0\Source1\Timer\Observer,RunLoop就会立马退出。
        CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
        
        //销毁source
        CFRelease(source);
        
        //启动RunLoop
        /**
         第二个参数:RunLoop过期时间
         第三个参数:returnAfterSourceHandled,设置为true,代表执行完source后就会退出当前loop;
                                             设置为false,代表执行完source后不会退出当前loop。
         */
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
        
        NSLog(@"----end------");
        }];
        
        [self.innerThread start];
    }
    return self;
}

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

- (void)executeTask:(MJPermenantThreadTask)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
{
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.innerThread = nil;
}

- (void)__executeTask:(MJPermenantThreadTask)task
{
    task();
}
上一篇下一篇

猜你喜欢

热点阅读