13.runloop 解决常驻线程

问题

1.整么样在子线程中启动一个runloop
2.整么样结束某一个线程中的runloop
3.整么用runloop 封装一个常驻线程(也就是线程保活)

答案

1.整么样在子线程中启动一个runloop

1.C语言方式

// 这个是创建一个线程
   self.innerThread = [[FAN_BaseThread alloc] initWithBlock:^{
        
        NSLog(@"begin----");

        // 通过C语言方式实现runloop 启动
        
        // 1.创建上下文
        CFRunLoopSourceContext context = {0};
        
        // 2.创建source 用来线程保活
        CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
        
        // 3.当前的runloop 添加source
        CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
        
        // 4. 销毁创建的 source
        CFRelease(source);
        
        // 5.启动runloop
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
        
        NSLog(@"end----");
    }];
  1. 通过OC方式启动runloop
        self.innerThread = [[MJThread alloc] initWithBlock:^{
            
            [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
            
            while (weakSelf && !weakSelf.isStopped) {
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            }
        }];
        
        [self.innerThread start];

2.整么样结束某一个线程中的runloop

// 1.结束某一个runloop 肯定实在某一条子线程中执行
  [self performSelector:@selector(__stop) onThread:self.innerThread withObject:nil waitUntilDone:YES];

- (void)__stop
{
// 这个就是结束当前的runloop 
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.innerThread = nil;
}

3.整么用runloop 封装一个常驻线程(也就是线程保活)

直接看源码吧

#import "FAN_PermenantThread.h"

/** FAN_BaseThread **/
@interface FAN_BaseThread : NSThread
@end
@implementation FAN_BaseThread
- (void)dealloc
{
    NSLog(@"%s", __func__);
}
@end

@interface FAN_PermenantThread()

@property (nonatomic,strong)FAN_BaseThread *innerThread;

@end

@implementation FAN_PermenantThread

- (instancetype)init
{
    self = [super init];
    if (self) {
        [self __initData];
    }
    return self;
}

- (void)dealloc{
    
    [self __stop];
    
    NSLog(@"%s",__func__);
}

#pragma mark public Method

/**
 开启线程
 */
- (void)run{
    
    if (!self.innerThread || self.innerThread.isExecuting) return;

    [self.innerThread start];
}

/**
 在当前子线程执行一个任务
 */
- (void)executeTask:(FAN_PermenantThreadTask)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];
}

#pragma mark private Method
- (void)__initData {
    
    self.innerThread = [[FAN_BaseThread alloc] initWithBlock:^{
        
        NSLog(@"begin----");

        // 通过C语言方式实现
        
        // 1.创建上下文
        CFRunLoopSourceContext context = {0};
        
        // 2.创建source 用来线程保活
        CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
        
        // 3.当前的runloop 添加source
        CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
        
        // 4. 销毁创建的 source
        CFRelease(source);
        
        // 5.启动runloop
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
        
        NSLog(@"end----");
    }];
    
}

- (void)__stop
{
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.innerThread = nil;
}

- (void)__executeTask:(FAN_PermenantThreadTask)task
{
    if (task) {
        task();
    }
}

@end

你可能感兴趣的:(13.runloop 解决常驻线程)