常驻线程
线程我们用来处理任务,但是一个线程只能同时处理一个任务,且在执行完任务后,就退出了.如果在执行下一个任务就需要重新开启一个线程,这样会不停的消耗CPU资源.基于此,我们就谈到了常驻线程这个概念.说到常驻线程,RunLoop就是一个常驻线程,它的存在,得以让程序随时处理事件,如果没有事件处理他会休眠.
下面我们就开始自己动手创建我们自己的常驻线程:
一:在默认全局常驻线程中执行操作(只要调用,默认线程及创建且不会销毁)
+ (void)excuteTask:(SXLivingThreadTask)task{
if (!task) {
return;
}
if (!sx_defaultThread) {
void(^createThreadBlock)(void) = ^{
NSRunLoop *currentRunloop = [NSRunLoop currentRunLoop];
[currentRunloop addPort:[NSPort new] forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
while (1) {
[currentRunloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
};
sx_defaultThread = [[NSThread alloc] initWithBlock:createThreadBlock];
[sx_defaultThread start];
}
[self performSelector:@selector(class_taskMethod:) onThread:sx_defaultThread withObject:task waitUntilDone:NO];
}
+ (void)class_taskMethod:(SXLivingThreadTask)task{
task();
}
二:自定义全局常驻线程中执行操作,创建了也是不会销毁的
+ (void)excuteTask:(SXLivingThreadTask)task identify:(NSString *)identify{
if (!task || !identify || identify.length == 0) {
return;
}
if (!sx_threadDictM) {
sx_threadDictM = [NSMutableDictionary dictionary];
}
NSThread *threadByIdentity = [sx_threadDictM objectForKey:identify];
if (!threadByIdentity) {
void(^createThreadBlock)(void) = ^{
CFRunLoopSourceContext content = {0};
CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &content);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
CFRelease(source);
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
};
threadByIdentity = [[NSThread alloc] initWithBlock:createThreadBlock];
[threadByIdentity start];
if (threadByIdentity) {
[sx_threadDictM setObject:threadByIdentity forKey:identify];
}
}
[threadByIdentity start];
[self performSelector:@selector(class_taskMethod:) onThread:threadByIdentity withObject:task waitUntilDone:NO];
}
三:在常驻默认线程中执行操作(线程需要随当前对象创建或销毁)
- (void)execureTask:(SXLivingThreadTask)task{
if (!task || !self.p_thread) {
return;
}
[self performSelector:@selector(threadTaskMothod:) onThread:self.p_thread withObject:task waitUntilDone:NO];
}
- (instancetype)init
{
self = [super init];
if (self) {
self.p_thread = [self thread];
}
return self;
}
- (void)dealloc{
[self performSelector:@selector(clearThreadMethod) onThread:self.p_thread withObject:nil waitUntilDone:YES];
}
- (NSThread *)thread{
NSThread *thread = nil;
__weak typeof(self) wealSelf = self;
void(^createThreadBlock)(void) = ^{
NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
[currentRunLoop addPort:[NSPort new] forMode:NSDefaultRunLoopMode];
while (wealSelf && wealSelf.isShouldKeepRunning) {
[currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
};
self.shouldKeepRunning = YES;
thread = [[NSThread alloc]initWithBlock:createThreadBlock];
[thread start];
return thread;
}
- (void)createThreadMethod:(void(^)(void))createThreadBlock{
createThreadBlock();
}
- (void)threadTaskMothod:(void(^)(void))task{
task ? task():nil;
}
- (void)clearThreadMethod{
self.shouldKeepRunning = NO;
CFRunLoopStop(CFRunLoopGetCurrent());
}