zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    NUMBER BASE CONVERSION(进制转换)
    2776 寻找代表元(匈牙利算法)
    最长严格上子序列(二分优化)
    c++ bitset类的使用和简介
    笨小猴 2008年NOIP全国联赛提高组
    三国游戏 2010年NOIP全国联赛普及组
    全国信息学奥林匹克联赛(NOIP2014)复赛 模拟题Day2 长乐一中
    codevs 1704 卡片游戏
    热浪
    全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中
  • 原文地址:https://www.cnblogs.com/ibelieveyou/p/6780098.html
Copyright © 2011-2022 走看看