直接上代码很好理解。
/**
说明:常驻线程
*/
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
typedef void (^ZZXPermenantThreadTask)(void);
@interface ZZXPermanentThread : NSObject
/// 开启子线程
/// @param task 任务
- (void)executeTask:(ZZXPermenantThreadTask)task;
/// 结束子线程
- (void)stop;
@end
NS_ASSUME_NONNULL_END
#import "ZZXPermanentThread.h"
/// ZZXThread
@interface ZZXThread : NSThread
@end
@implementation ZZXThread
- (void)dealloc{
NSLog(@"%s", __func__);
}
@end
@interface ZZXPermanentThread ()
@property (strong, nonatomic) ZZXThread *innerThread;
@end
@implementation ZZXPermanentThread
#pragma mark - init methods
- (instancetype)init{
if (self == [super init]) {
[self config];
}
return self;
}
- (void)config{
if (@available(iOS 10.0, *)) {
self.innerThread = [[ZZXThread alloc] initWithBlock:^{
// 创建上下文(要初始化一下结构体,否则结构体里面有可能是垃圾数据)
CFRunLoopSourceContext context = {0};
// 创建source
CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
// 往Runloop中添加source
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
// 销毁source
CFRelease(source);
// 启动
//参数:模式,过时时间(1.0e10一个很大的值),是否执行完source后就会退出当前loop
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
}];
} else {
// Fallback on earlier versions
}
[self.innerThread start];
}
- (void)dealloc{
NSLog(@"%s", __func__);
[self stop];
}
#pragma mark - Private methods
- (void)__stop{
CFRunLoopStop(CFRunLoopGetCurrent());
self.innerThread = nil;
}
- (void)__executeTask:(ZZXPermenantThreadTask)task{
task();
}
#pragma mark - Event Response
#pragma mark - public methods
- (void)executeTask:(ZZXPermenantThreadTask)task{
if (!self.innerThread || !task) return;
[self performSelector:@selector(__executeTask:)
onThread:self.innerThread
withObject:task
waitUntilDone:NO];
}
- (void)stop{
if (!self.innerThread) return;
//waitUntilDone:YES 等到子线程任务执行完再执行下面NSLog
//NO 不用等到子线程执行完再执行下面NSLog(下面NSLog在主线程,test在子线程,同时执行)
[self performSelector:@selector(__stop)
onThread:self.innerThread
withObject:nil
waitUntilDone:YES];
NSLog(@"退出");
}
@end