自定义子线程MZChildThread
//MZChildThread.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MZChildThread : NSObject
///在子线程中执行任务
- (void)executeTask:(void(^)(void))task;
///停止并销毁线程
- (void)stopThread;
@end
NS_ASSUME_NONNULL_END
//MZChildThread.m
#import "MZChildThread.h"
#if DEBUG
#ifndef MZPrivateThreadLog
#define MZPrivateThreadLog(...) NSLog(__VA_ARGS__)
#else
#define MZPrivateThreadLog(...)
#endif
#endif
#pragma mark - _MZPrivateThread
@interface MZPrivateThread : NSThread
@end
@implementation MZPrivateThread
- (void)dealloc {
MZPrivateThreadLog(@"%s", __func__);
}
@end
#pragma mark - MZChildThread
@interface MZChildThread ()
@property (nonatomic, strong) MZPrivateThread *thread;
@property (nonatomic, assign) BOOL shouldStop;
@end
@implementation MZChildThread
#pragma mark - public Methods
- (instancetype)init {
if (self = [super init]) {
__weak typeof(self) weakSelf = self;
self.shouldStop = NO;
self.thread = [[MZPrivateThread alloc] initWithBlock:^{
//将端口作为输入源添加到运行循环的指定模式
[[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
while (weakSelf && !weakSelf.shouldStop) {
//相当于run,但又与run不同的是,可以自己控制退出时机
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
//当线程保活时,该打印将被阻塞
MZPrivateThreadLog(@"===end===");
}];
//开启线程
[self.thread start];
}
return self;
}
- (void)executeTask:(void (^)(void))task {
if (!self.thread || !task) return;
[self performSelector:@selector(p_executeTask:) onThread:self.thread withObject:task waitUntilDone:NO];
}
- (void)stopThread {
if (!self.thread) return;
//waitUntilDone为YES,表示执行完子线程代码后,才执行之后的代码
[self performSelector:@selector(p_stopThread) onThread:self.thread withObject:nil waitUntilDone:YES];
}
#pragma mark - public Methods
- (void)p_executeTask:(void (^)(void))task {
task();
}
- (void)p_stopThread {
self.shouldStop = YES;
//停止当前线程(一定要在开启的子线程中关闭),之后会解除阻塞
CFRunLoopStop(CFRunLoopGetCurrent());
self.thread = nil;
}
- (void)dealloc {
//在释放的时候,要关闭线程,防止占用资源
[self stopThread];
MZPrivateThreadLog(@"%s", __func__);
}
@end
使用
#import "DetailViewController.h"
#import "MZChildThread.h"
@interface DetailViewController ()
@property (nonatomic, strong) MZChildThread *thread;
@end
@implementation DetailViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.thread = [[MZChildThread alloc] init];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.thread executeTask:^{
NSLog(@"执行任务在 - %@", [NSThread currentThread]);
}];
}
- (IBAction)stop {
[self.thread stopThread];
}
- (void)dealloc {
NSLog(@"%s", __func__);
}
@end
网友评论