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
  • 相关阅读:
    系统tabbar出现两个tabbar的问题解决方案。
    iOS 开发苹果由http改为https 之后,如果服务器不做相应的修改,那么客户端需要做点更改
    UIAlertController的一些简单实用方法
    ios开发同一个lab显示不同的颜色
    ios开发同一个版本多次提交不想改变版本号的解决方法
    iOS开发textfield的一些方法汇总
    C#笔记
    Shader之性能优化
    Shader之ShaderUI使用方法
    Shader Example
  • 原文地址:https://www.cnblogs.com/ibelieveyou/p/6780098.html
Copyright © 2011-2022 走看看