对定时器与滚动视图冲突处理

本文介绍了一个iOS应用中RunLoop的应用实例,展示了如何使用NSTimer和GCD实现定时任务,并探讨了不同模式下RunLoop对定时器的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

直接上代码。

//

//  ViewController.m

//  TestRunLoop

//

//  Created by 赵诣 on 2016/11/11.

//  Copyright © 2016 赵诣. All rights reserved.

//


#import "ViewController.h"

#import "MarkRunLoopViewController.h"


@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>

{

    NSTimer *myTimer;

    

    UILabel *mylabel;

    

    

    dispatch_queue_t global_queue;

    dispatch_queue_t main_queue;

}


@property (nonatomic, strong) UITableView *table;


@property (nonatomic, strong) dispatch_source_t timer;


@end


@implementation ViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    

    //NSRunLoop 一般用于延迟,定时

    

    mylabel = [[UILabel alloc] initWithFrame:CGRectMake(50, 50, 300, 60)];

    mylabel.text = @"我爱领美";

    mylabel.textAlignment = NSTextAlignmentCenter;

    mylabel.textColor = [UIColor blackColor];

    mylabel.backgroundColor = [UIColor yellowColor];

    [self.view addSubview:mylabel];

    

    

    global_queue = dispatch_get_global_queue(0, 0);

    main_queue = dispatch_get_main_queue();

    

#if 1

    

    //一个常见的问题就是,主线程中一个NSTimer添加在default mode中,当界面上有一些scroll view的滚动频繁发生导致run loop运行在UItraking mode中,从而这个timer没能如期望那般的运行。所以,我们就可以把这个timer加到NSRunLoopCommonModes中来解决。

    

    myTimer = [NSTimer timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {

        mylabel.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];

        

        mylabel.textColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];

    }];

    

    [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];

    

    

#endif

    

    

#if 0

    //GCD定时器

    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, main_queue);

    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC));//开始时间

    uint64_t interval = (uint64_t)(0.3 * NSEC_PER_SEC);//间隔

    dispatch_source_set_timer(self.timer, start, interval, 0);

    

    dispatch_source_set_event_handler(self.timer, ^{

//        dispatch_async(global_queue, ^{

//            dispatch_async(main_queue, ^{

                mylabel.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];

                

                mylabel.textColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];

//            });

//        });

    });

    

    dispatch_resume(self.timer);

//    dispatch_cancel(self.timer);

    

#endif

    

#if 0


    dispatch_async(global_queue, ^{

        // 1种方式(初始化方法带scheduled) ->  此种方式创建的timer已经添加至runloop

         [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {

             mylabel.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];

             

             mylabel.textColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];

         }];

        //已经将nstimer添加到NSRunloop中了

        //保持线程为活动状态,才能保证定时器执行

         [[NSRunLoop currentRunLoop] run];

        

        

        //2种方式(初始化方法不带scheduled) ->  此种方式创建的timer没有添加至runloop

//        myTimer = [NSTimer timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {

//            mylabel.backgroundColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];

//            

//            mylabel.textColor = [UIColor colorWithRed:arc4random() % 256 / 255.0 green:arc4random() % 256 / 255.0 blue:arc4random() % 256 / 255.0 alpha:1];

//        }];

        //将定时器添加到runloop

//        [[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];

//        [[NSRunLoop currentRunLoop] run];

    });

    

#endif

    [self createTableView];

}



- (void)createTableView

{

    self.table = [[UITableView alloc] initWithFrame:CGRectMake(0, 150, 400, 400) style:(UITableViewStyleGrouped)];

    self.table.dataSource = self;

    self.table.delegate = self;

    self.table.backgroundColor = [UIColor redColor];

    

    [self.view addSubview:self.table];

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

{

    return 1;

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

    return 10;

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"DVCell"];

    if (!cell) {

        cell = [[UITableViewCell alloc] initWithStyle:(UITableViewCellStyleSubtitle) reuseIdentifier:@"DVCell"];

    }

    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

{

    return 50;

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

    MarkRunLoopViewController *runloop = [[MarkRunLoopViewController alloc] init];

    

    [self presentViewController:runloop animated:YES completion:nil];

}


- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section

{

    return 0.01;

}


- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section

{

    return 0.01;

}


- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

{

    return nil;

}


- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section

{

    return nil;

}




@end



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值