• iOS


    原创

     

     定时器里面有个runloop mode,一般定时器是运行在defaultmode上。但是如果滑动了这个页面,主线程runloop会转到UITrackingRunLoopMode中,这时候就不能处理定时器了,造成定时器失效,原因就是runroop mode的问题

    • NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
    • UITrackingRunLoopMode:ScrollView滑动时会切换到该Mode
    • UIInitializationRunLoopMode:run loop启动时,会切换到该Mode
    • NSRunLoopCommonModes(kCFRunLoopCommonModes)

     

    这里提供了两种解决办法: 
        1. 把定时器添加到当前线程消息循环中 并指定消息循环的模式为
    NSRunLoopCommonModes(无论runloop运行在哪个mode,都能运行)
        2. 切换到主线程上更新UI
        // 步骤1. 把NSTimer放到子线程中,但是要注意:因为自线程的消息循环默认不开启,所以这里还需要开启一下子线程的消息循环
        // 步骤2. 切换到主线程上更新UI
     
    #import "ViewController.h"

    @interface ViewController ()

    @property(nonatomic,strong)UIScrollView *scrollView;
    @property(nonatomic,strong)NSTimer *timer;

    @property(nonatomic,strong)UILabel *label;
    @property(nonatomic,assign)float times;

    @end

    @implementation ViewController

    - (void)viewDidLoad {
        [super viewDidLoad];

        self.scrollView = [[UIScrollView alloc]init];
        self.scrollView.frame = self.view.frame;
        self.scrollView.backgroundColor = [UIColor cyanColor];
        self.scrollView.contentSize = CGSizeMake(375, 2000);
        [self.view addSubview:self.scrollView];
       
        self.label = [[UILabel alloc]init];
        self.label.frame = CGRectMake(100, 100, 100, 100);
        self.label.backgroundColor = [UIColor whiteColor];
        [self.view addSubview:self.label];
       
        _times = 0;

        //self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(demo) userInfo:nil repeats:YES];
       
        //  解决方法1: 把定时器添加到当前线程消息循环中 并指定消息循环的模式为
        //  cNSRunLoopCommonModes(无论runloop运行在哪个mode,都能运行)
        //  加上这句完美解决
        //[[NSRunLoop currentRunLoop]addTimer:self.timer forMode:NSRunLoopCommonModes];
       
        //  解决方法2:
        // 1. 把NSTimer放到子线程中,但是要注意:因为自线程的消息循环默认不开启,所以这里还需要开启一下子线程的消息循环
        // 2. 切换到主线程上更新UI
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
           
            self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(demo) userInfo:nil repeats:YES];
            [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
            [[NSRunLoop currentRunLoop] run];
           
        });
    }

    -(void)demo{
       
        _times+=0.1;
       
        //self.label.text = [NSString stringWithFormat:@"%f",_times];

       
        //  队列方式(在主线程上更新UI)
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.label.text = [NSString stringWithFormat:@"%f",_times];
        }];
       
        //  GCD方式
        /*dispatch_async(dispatch_get_main_queue(), ^{
           
            self.label.text = [NSString stringWithFormat:@"%f",_times];
        });*/
    }

    @end
  • 相关阅读:
    Python-TXT文本操作
    Appium-处理系统弹窗
    Appium-服务关键字
    App Inspector-iOS真机功能详解
    Appium+Python3+iOS真机环境搭建
    Appium-超过60s的应用场景如何处理
    python-入门的第一个爬虫例子
    Mysql(五) JDBC
    Mysql(四)正则表达式
    Mysql(三)约束
  • 原文地址:https://www.cnblogs.com/ibelieveyou/p/6780098.html
Copyright © 2020-2023  润新知