线程保活

2020-09-12  本文已影响0人  Aliv丶Zz

在实际开发中,我们可能很多操作需要放在子线程中操作,可能会重复的创建线程。这个时候我们就需要创建一个线程并不让其销毁,然后将需要放在子线程中的操作放在里面进行。

实例:

.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

typedef void(^ZLXThreadTask)(void);

@interface ZLXPerennialThread : NSObject

//-(void)run;

/**
执行任务
 */

-(void)executeTask:(ZLXThreadTask) task;

/**
停止线程
 */
-(void)stop;

@end

NS_ASSUME_NONNULL_END

.m

#import "ZLXPerennialThread.h"
@interface ZLXThread : NSThread
@end
@implementation ZLXThread
-(void)dealloc{
    NSLog(@"-- %s --",__func__);
}
@end


@interface ZLXPerennialThread()
@property (nonatomic, strong) ZLXThread *interThread;
@property (nonatomic, assign, getter=isStop) BOOL stop;


@end

@implementation ZLXPerennialThread

- (instancetype)init
{
    self = [super init];
    if (self) {
        __weak typeof(self) weakSelf = self;

        self.interThread = [[ZLXThread alloc] initWithBlock:^{
#if 0
            // OC runloop
            [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc]init] forMode:NSDefaultRunLoopMode];
                   while (weakSelf && !weakSelf.isStop) {
                       [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
                   }
#else
            // C runloop   {0}:初始化结构体,如果不初始化,可能数据错乱
            CFRunLoopSourceContext context = {0};
            CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
            CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
        #if 0
            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
        #else
            while (weakSelf && !weakSelf.isStop) {
                 /**
                  1.0e10: CFRunLoopRun()  源码中 的默认值
                   true:returnAfterSourceHandled执行完后,退出当前runloop
                  */
                 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, true);
             }
        #endif
#endif
        }];
        [self.interThread start];

    }
    return self;
}

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

-(void)executeTask:(ZLXThreadTask)task{
    
    if (!self.interThread || !task) return;
    
    if (!self.interThread.isExecuting) {
        [self.interThread start];
    }
    
    [self performSelector:@selector(__executeTask:) onThread:self.interThread withObject:task waitUntilDone:YES];

}

-(void)stop{
    if (!self.interThread) return;
    
    [self performSelector:@selector(__stop) onThread:self.interThread withObject:nil waitUntilDone:YES];

}

#pragma -makr privet methods

-(void)__stop{
    self.stop = YES;
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.interThread = nil;

}

-(void)__executeTask:(ZLXThreadTask)task{
    task();
}

-(void)dealloc{
    [self stop];
    NSLog(@"ZLXPerennialThread dealloc");
}
@end
上一篇 下一篇

猜你喜欢

热点阅读