在实际开发中,我们可能很多操作需要放在子线程中操作,可能会重复的创建线程。这个时候我们就需要创建一个线程并不让其销毁,然后将需要放在子线程中的操作放在里面进行。
实例:
.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
网友评论