基于Runloop 来实现手动保持线程生命周期

概要:开发者自己建立一个线程 ,触摸屏幕的时候会将让子线程去执行一个方法test 就是答应当前的线程对象;利用runloop中添加一个port来唤醒runloop来执行子线程活跃,并设置一个flag可以动释放改线程.

唤醒runloop

  [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];

重写run方法 

  [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];

注意不能使用 [NSRunLoop currentRunLoop] run] 因为它创立了一个永远也不能停止的runloop

 

核心代码:

self.thread = [[MyThread alloc] initWithBlock:^{

        NSLog(@"%@---begin---",[NSThread currentThread]);

//

        [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];

        while (!weakSelf.stopped) {

            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];

        }

        //[NSRunLoop currentRunLoop] run] 开启了一个永不销毁的runloop

        

        NSLog(@"%@---end---",[NSThread currentThread]);

    }];

 

 

 

代码如下:

//

//  NextViewController.m

//  RunLoop-线程保活

//

//  Created by edz on 2020/3/4.

//  Copyright © 2020 mende. All rights reserved.

//

 

#import "NextViewController.h"

 

#import "MyThread.h"

 

@interface NextViewController ()

 

@property (nonatomic, strong) MyThread *thread;

 

@property (nonatomic,assign) BOOL stopped;

 

@end

 

@implementation NextViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    [self.view setBackgroundColor:[UIColor orangeColor]];

    // Do any additional setup after loading the view.

    __weak typeof (self) weakSelf = self;

    UIButton *nextBtn = [UIButton buttonWithType:UIButtonTypeCustom];

    nextBtn.frame = CGRectMake(50, 200, 150, 50);

    [nextBtn setTitle:@"STOP" forState:UIControlStateNormal];

    [nextBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];

    [nextBtn addTarget:self action:@selector(stop) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:nextBtn];

    

    self.thread = [[MyThread alloc] initWithBlock:^{

        NSLog(@"%@---begin---",[NSThread currentThread]);

        [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];

        while (!weakSelf.stopped) {

            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantPast]];

        }

        //[NSRunLoop currentRunLoop] run] 开启了一个永不销毁的runloop

        

        NSLog(@"%@---end---",[NSThread currentThread]);

    }];

    

    [self.thread start];

    

}

 

//手动控制停止runloop中某个线程

- (void)stop{

    

    [self performSelector:@selector(stopThread) onThread:self.thread withObject:nil waitUntilDone:NO];

}

 

//子线程调用方法

- (void)stopThread{

    self.stopped = YES;

    CFRunLoopStop(CFRunLoopGetMain());

    

    NSLog(@"%s   %@",__func__,[NSThread currentThread]);

}

//点击屏幕触 在子线程中执行某个方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    

    [self performSelector:@selector(test) onThread:self.thread withObject:nil waitUntilDone:NO];

}

 

//子线程执行方法

- (void)test{

    

    NSLog(@"%s  %@",__func__,[NSThread currentThread]);

}

 

- (void)dealloc{

    

    NSLog(@"%s",__func__);

   

//    [self stop];

}

 

/*

#pragma mark - Navigation

 

// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    // Get the new view controller using [segue destinationViewController].

    // Pass the selected object to the new view controller.

}

*/

 

@end

你可能感兴趣的:(个人OC知识梳理)