美文网首页IOS知识积累iOS技术点多线程
# iOS线程保活(常驻线程)

# iOS线程保活(常驻线程)

作者: Jason_YZC | 来源:发表于2019-01-03 12:33 被阅读26次

介绍

在日常的iOS开发中,遇到卡顿也是在所难免,一般卡顿是由于主线程处理耗时长的操作而造成线程一直在阻塞,那么我们可以去建立子线程,把耗时操作放在子线程去做,这样是完全没问题。 这样就会有一个问题,子线程处理完操作之后就会被销毁,想再处理其他事情,必须再开启新的子线程。如果想要一个子线程去持续处理事情,那么就需要这个线程一直存活在后台,在需要的时候随时可以唤醒。

下面提供两种线程保活的方案就可以做到保活,在有任务的时候唤醒来做事情, 线程没任务时会进入休眠状态。

方案一

//头文件
typedef void (^YZCPermenantThreadTask)(void);

@interface YZCPermenantThread : NSObject

- (void)executeTask:(YZCPermenantThreadTask)task;

- (void)cancelTask;
@end


//==========.m文件================
#import "YZCPermenantThread.h"

#pragma mark - YZCThread
@interface YZCThread : NSThread
@end
@implementation YZCThread
-(void)dealloc {
    NSLog(@"%s",__func__);
}
@end

#pragma mark - YZCPermenantThread
@interface YZCPermenantThread()
@property (nonatomic, strong) YZCThread *innerThread;
@property (nonatomic, assign, getter=isStopped) BOOL stopped;
@end


@implementation YZCPermenantThread

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.stopped = NO;
        
        __weak typeof(self) weakSelf = self;
        self.innerThread = [[YZCThread alloc] initWithBlock:^{
            [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init]
                                        forMode:NSDefaultRunLoopMode];
            
            while (weakSelf && !weakSelf.isStopped) {
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
                                         beforeDate:[NSDate distantFuture]];
            }
        }];
        
        [self.innerThread start];
    }
    return self;
}

- (void)executeTask:(YZCPermenantThreadTask)task {
    if (!self.innerThread || !task) return;
    
    [self performSelector:@selector(__executeTask:) onThread:self.innerThread
               withObject:task waitUntilDone:NO];
}

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

#pragma mark - private
- (void)stop {
    self.stopped = YES;
    CFRunLoopStop(CFRunLoopGetCurrent());
    self.innerThread = nil;
}

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

方案二

方案二只是核心实现不一样,其他基本一致,相比方案一去除了标记,直接使用CFRunLoop去做

- (instancetype)init
{
    if (self = [super init]) {
        self.innerThread = [[YZCPermenantThread alloc] initWithBlock:^{
            NSLog(@"begin----");
            
            // 创建上下文(要初始化一下结构体)
            CFRunLoopSourceContext context = {0};
            
            // 创建source
            CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
            
            // 往Runloop中添加source
            CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
            
            // 销毁source
            CFRelease(source);
            
            // 启动
            CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0e10, false);
            
            NSLog(@"end----");
        }];
        
        [self.innerThread start];
    }
    return self;
}

调用

外面调用就相对比较简单,因为上面已经封装好了

#import "ViewController.h"
#import "YZCPermenantThread.h"

@interface ViewController ()
@property (nonatomic, strong) YZCPermenantThread *thread;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.thread = [[YZCPermenantThread alloc] init];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.thread executeTask:^{
        NSLog(@"执行了任务:%@",[NSThread currentThread]);
    }];
}

相关文章

  • # iOS线程保活(常驻线程)

    介绍 在日常的iOS开发中,遇到卡顿也是在所难免,一般卡顿是由于主线程处理耗时长的操作而造成线程一直在阻塞,那么我...

  • iOS底层原理——浅谈RunLoop

    RunLoop应用:线程保活 线程保活、控制销毁 iOS-浅谈RunLoop8iOS底层原理总结 - RunLoo...

  • iOS NSThread 保活线程代码封装

    iOS NSThread 保活线程代码封装

  • iOS开发-使用Runloop实现线程保活、线程常驻

    保证线程的长时间存活在iOS开发过程中,有时一些花费时间比较长的操作阻塞主线程,导致界面卡顿,那么我们就会创建一个...

  • iOS 线程保活

    [self performSelectorInBackground:@selector(dealInsertMo...

  • iOS 线程保活

    1、线程保活管理类.h文件 // // ZFPermenantThread.h // ZFThread // //...

  • iOS线程保活

    简介 大家好!我是Tony,一个热爱技术,希望运用技术改变生活的的追梦男孩。闲话不多说,今天聊聊iOS的线程保活。...

  • iOS:线程保活

    自定义子线程MZChildThread 使用

  • iOS 线程保活

    开发中,经常会遇到将耗时操作放到子线程中执行,来提升应用性能的场景。当子线程中的任务执行完毕后,线程就被立刻销毁。...

  • iOS线程保活

    一.什么是线程保活 如图1所以,任务执行完成后,线程会退出。线程的创建和销毁比较耗性能,如果需要在一条线程中频繁的...

网友评论

    本文标题:# iOS线程保活(常驻线程)

    本文链接:https://www.haomeiwen.com/subject/jbffrqtx.html