美文网首页
iOS 底层 - runloop之用C语言实现线程保活

iOS 底层 - runloop之用C语言实现线程保活

作者: 水中的蓝天 | 来源:发表于2020-04-06 14:56 被阅读0次

    本文源自本人的学习记录整理与理解,其中参考阅读了部分优秀的博客和书籍,尽量以通俗简单的语句转述。引用到的地方如有遗漏或未能一一列举原文出处还望见谅与指出,另文章内容如有不妥之处还望指教,万分感谢 !

    XYHPermenantThread

    XYHPermenantThread .h

    #import <Foundation/Foundation.h>
    
    typedef void (^XYHPermenantThreadTask)(void);
    
    @interface XYHPermenantThread : NSObject
    
    /**
     在当前子线程执行一个任务
     */
    - (void)executeTask:(XYHPermenantThreadTask)task;
    
    /**
     结束线程
     */
    - (void)stop;
    
    @end
    

    XYHPermenantThread.m

    #import "XYHPermenantThread.h"
    
    /** XYHThread **/
    @interface XYHThread : NSThread
    @end
    @implementation XYHThread
    - (void)dealloc
    {
        NSLog(@"%s", __func__);
    }
    @end
    
    /** XYHPermenantThread **/
    @interface XYHPermenantThread()
    @property (strong, nonatomic) XYHThread *innerThread;
    @end
    
    @implementation XYHPermenantThread
    #pragma mark - public methods
    - (instancetype)init
    {
        if (self = [super init]) {
    
            self.innerThread = [[XYHThread alloc] initWithBlock:^{
                NSLog(@"begin----");
                
                // 创建上下文(要初始化一下结构体)
                CFRunLoopSourceContext context = {0};
                
                // 创建source
                CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
                
                // 往Runloop中添加source
                CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
                
                // 销毁source
                CFRelease(source);
               
               /** 
               启动loop
               第3个参数:returnAfterSourceHandled,
               设置为true,代表执行完source后就会退出当前loop
               设置为false,代表执行完source后就不在退出当前loop
               */
               CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
    
                NSLog(@"end----");
            }];
            //开始跑起来
            [self.innerThread start];
        }
        return self;
    }
    
    - (void)executeTask:(XYHPermenantThreadTask)task
    {
        if (!self.innerThread || !task) return;
    
        //执行任务时wait需要设置为NO,不需要别人等;这种操作在RunLoop中是属于Sources0
        [self performSelector:@selector(__executeTask:) onThread:self.innerThread withObject:task waitUntilDone:NO];
    
    }
    
    - (void)stop
    {
        if (!self.innerThread) return;
        
      //暂停时wait需要设置为YES;因为需要别人等,防止还没停止当前实例对象就先释放掉了。这种操作在RunLoop中是属于Sources0
        [self performSelector:@selector(__stop) onThread:self.innerThread withObject:nil waitUntilDone:YES];
    }
    
    #pragma mark - private methods
    - (void)__stop
    {
        CFRunLoopStop(CFRunLoopGetCurrent());
        self.innerThread = nil;
    }
    
    - (void)__executeTask:(XYHPermenantThreadTask)task
    {
        task();
    }
    
    #pragma mark - dealloc
    - (void)dealloc
    {
        NSLog(@"%s", __func__);
        
        [self stop];
    }
    @end
    

    使用:-------->>>>>>>>>>>>>>>--------

    #import "ViewController.h"
    #import "XYHPermenantThread.h"
    
    @interface ViewController ()
    @property (strong, nonatomic) XYHPermenantThread *thread;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.thread = [[XYHPermenantThread alloc] init];
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        [self.thread executeTask:^{
            NSLog(@"执行任务 - %@", [NSThread currentThread]);
        }];
    }
    
    - (IBAction)stop {
        [self.thread stop];
    }
    
    - (void)dealloc
    {
        NSLog(@"%s", __func__);
    }
    

    相关文章

      网友评论

          本文标题:iOS 底层 - runloop之用C语言实现线程保活

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