Runloop 小记02

100 阅读1分钟
  • 记录Runloop在实际项目中的运用

NSTimer

  • 滑动UIScrollView 时不打印
[NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
    NSLog(@"打印");
}];
  • NSDefaultRunLoopMode 和 UITrackingRunLoopMode
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
    NSLog(@"打印");
}];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; // NSDefaultRunLoopMode 默认Mode滑动时不打印
[[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode]; // 滑动的时打印
  • 或者直接设置NSRunLoopCommonModes标记
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

线程保活

@interface CRThread : NSThread
@end
@implementation CRThread

- (void)dealloc
{
    NSLog(@"%s",__FUNCTION__);
}

@end
@interface RunloopController ()
@property(nonatomic,strong)CRThread *thread;
@property(nonatomic,assign)BOOL isStopRunloop; // 标记是否停止Runloop
@end

@implementation RunloopController

- (void)viewDidLoad {

    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    self.isStopRunloop = NO;
    [self.thread start]; // 开启线程
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self performSelector:@selector(doSomething) onThread:self.thread withObject:nil waitUntilDone:YES];
}

//  在当前子线程做任务
-(void)doSomething
{
    NSLog(@"做任务 - %@",[NSThread currentThread]);
}

//退出Runloop
-(void)exitRunloop
{
    self.isStopRunloop = YES;
    CFRunLoopStop(CFRunLoopGetCurrent());
}

#pragma mark - lazy load
- (CRThread *)thread
{
    if (!_thread) {
        // 这种方式会造成thread对控制器的强引用,不能使控制器正常销毁
        // _thread = [[CRThread alloc] initWithTarget:self selector:@selector(run) object:nil];
        __weak typeof(self) weakSelf = self;
        _thread = [[CRThread alloc] initWithBlock:^{
            // 保活线程
            [[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
            while (weakSelf && (weakSelf.isStopRunloop == NO)) {
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
            }
            NSLog(@"退出Runloop");
        }];
    }
    return _thread;
}

-(void)dealloc
{
    [self performSelector:@selector(exitRunloop) onThread:self.thread withObject:nil waitUntilDone:YES];
    NSLog(@"%s",__FUNCTION__);
}

@end