码迷,mamicode.com
首页 > 移动开发 > 详细

iOS - scrollView与NSTimer的失效问题详解

时间:2017-04-28 10:25:56      阅读:243      评论:0      收藏:0      [点我收藏+]

标签:size   void   uila   efault   ios   原创   round   demo   patch   

原创

 

 定时器里面有个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

iOS - scrollView与NSTimer的失效问题详解

标签:size   void   uila   efault   ios   原创   round   demo   patch   

原文地址:http://www.cnblogs.com/ibelieveyou/p/6780098.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!