美文网首页
RunLoop-线程的封装

RunLoop-线程的封装

作者: 越天高 | 来源:发表于2020-11-09 10:09 被阅读0次

01接口设计

以后我们使用线程的时候,自己控制线程的生命周期,我们可以自己封装一个小工具,可控制生命周期的线程

02 内部实现

#import "SLPermenantThread.h"
@interface MyThread : NSThread

@end
@implementation MyThread
- (void)dealloc
{
    NSLog(@"MyThread dealloc");

}
@end


/*SLPermenantThread */
@interface SLPermenantThread ()
@property (nonatomic, strong)  MyThread *myThread;
@property (nonatomic, assign)  BOOL stopped;

@end

@implementation SLPermenantThread

- (instancetype)init
{
    self = [super init];
    if (self)
    {
        self.stopped = NO;
        __weak typeof(self) weakSelf = self;
        self.myThread = [[MyThread alloc] initWithBlock:^{
            [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc]init] forMode:NSDefaultRunLoopMode];
            while (weakSelf && !weakSelf.stopped)
            {
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            }
        }];
        
    }
    return self;
}

- (void)run
{
    NSLog(@"开启线程");
    if (!self.myThread) return;
    [self.myThread start];

}
- (void)stop
{
    if (!self.myThread) return;
    
    [self performSelector:@selector(__stop) onThread:self.myThread withObject:nil waitUntilDone:YES];
    
}
- (void)executeThreadBlock:(SLPermenantThreadBlock)block
{
    if (!self.myThread && !block) return;
    [self performSelector:@selector(__executeBlock:) onThread:self.myThread withObject:block waitUntilDone:NO];
}
-(void)__stop
{
    self.stopped = YES;
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.myThread = nil;
}
- (void)__executeBlock:(SLPermenantThreadBlock)block
{
    block();
}

- (void)dealloc
{
    NSLog(@"wode 先层dealloc");

}
@end

03用C语言实现

//创建一个上下文
    CFRunLoopSourceContext context = {0};//局部变量在每初始化之前他里面的值是乱的,我们给他一个默认的值0,

    //创建source
    CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
    //添加source
    CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
    //CF框架中使用create和copy开头创建出来的都需要我们自己销毁
    CFRelease(source);
    //开启runloop //这个执行完一次任务就会退出,所以需要我们自己手动加循环
    while (1)
    {
        //3true,代表执行完source就会返回退出当前的loop 改成false,就不用加这个while循环了
        CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, true);
    }

答疑

我们什么时候会用到手动开启RunLoop,
当我在一个子线程中频繁进行一个操作的时候,重复的创建和销毁线程比较消耗性能,我们就可以创建一条线程,每次都让他执行,前提线程是可以串行的

相关文章

网友评论

      本文标题:RunLoop-线程的封装

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