ios 中定时器:NSTimer, CADisplayLink, GCD

时间:2021-10-19 00:05:59
  1 #import "ViewController.h"
  2 #import "RunloopViewController.h"
  3 @interface ViewController ()
  4 
  5 @property (nonatomic , assign) NSInteger currentIndex;
  6 
  7 @property (nonatomic) CADisplayLink * timerInC;
  8 
  9 @property (nonatomic) UIImageView * imgV;
 10 
 11 @property (nonatomic) NSTimer * timerInN;
 12 
 13 @property (nonatomic) dispatch_source_t timerInG;
 14 
 15 @property (nonatomic , assign) BOOL nsTimerResume;
 16 
 17 @property (nonatomic , assign) BOOL gcdTimerResume;
 18 
 19 @end
 20 
 21 @implementation ViewController
 22 
 23 - (void)viewDidLoad {
 24     [super viewDidLoad];
 25     
 26     self.view.backgroundColor = [UIColor grayColor];
 27     
 28     self.imgV = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
 29     self.imgV.contentMode = UIViewContentModeScaleAspectFill;
 30     self.imgV.center = self.view.center;
 31     [self.view addSubview:self.imgV];
 32     
 33     
 34     UIButton * button = [UIButton buttonWithType:(UIButtonTypeSystem)];
 35     [button setFrame:CGRectMake(0, 0, 100, 30)];
 36     button.center = CGPointMake(self.view.center.x - 110, self.view.center.y + 200);
 37     [self.view addSubview:button];
 38     [button setTitle:@"CADisplayLink" forState:(UIControlStateNormal)];
 39     [button setBackgroundColor:[UIColor whiteColor]];
 40     [button addTarget:self action:@selector(CADisplayLinkAction) forControlEvents:(UIControlEventTouchUpInside)];
 41     
 42     UIButton * button1 = [UIButton buttonWithType:(UIButtonTypeSystem)];
 43     [button1 setFrame:CGRectMake(0, 0, 100, 30)];
 44     button1.center = CGPointMake(self.view.center.x, self.view.center.y + 200);
 45     [self.view addSubview:button1];
 46     [button1 setTitle:@"NSTimer" forState:(UIControlStateNormal)];
 47     [button1 setBackgroundColor:[UIColor whiteColor]];
 48     [button1 addTarget:self action:@selector(NSTimerAction) forControlEvents:(UIControlEventTouchUpInside)];
 49     
 50     
 51     UIButton * button2 = [UIButton buttonWithType:(UIButtonTypeSystem)];
 52     [button2 setFrame:CGRectMake(0, 0, 100, 30)];
 53     button2.center = CGPointMake(self.view.center.x + 110, self.view.center.y + 200);
 54     [self.view addSubview:button2];
 55     [button2 setTitle:@"GCDTimer" forState:(UIControlStateNormal)];
 56     [button2 setBackgroundColor:[UIColor whiteColor]];
 57     [button2 addTarget:self action:@selector(GCDTimerAction) forControlEvents:(UIControlEventTouchUpInside)];
 58     
 59     UIButton * button3 = [UIButton buttonWithType:(UIButtonTypeSystem)];
 60     [button3 setFrame:CGRectMake(0, 0, 100, 30)];
 61     button3.center = CGPointMake(self.view.center.x, self.view.center.y + 240);
 62     [self.view addSubview:button3];
 63     [button3 setTitle:@"看看Runloop" forState:(UIControlStateNormal)];
 64     [button3 setBackgroundColor:[UIColor whiteColor]];
 65     [button3 addTarget:self action:@selector(gotoRunloopAction) forControlEvents:(UIControlEventTouchUpInside)];
 66 }
 67 
 68 -(void)viewWillAppear:(BOOL)animated
 69 {
 70     [self initTimer];
 71 }
 72 
 73 -(void)initTimer
 74 {
 75     ///target selector 模式初始化一个实例
 76     self.timerInC = [CADisplayLink displayLinkWithTarget:self selector:@selector(changeImg)];
 77     ///暂停
 78     self.timerInC.paused = YES;
 79     ///selector触发间隔
 80     self.timerInC.frameInterval = 2;
 81     ///加入一个runLoop
 82     [self.timerInC addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
 83     self.timerInN = [NSTimer timerWithTimeInterval:0.032 target:self selector:@selector(changeImg) userInfo:nil repeats:YES];
 84     self.timerInN.fireDate = [NSDate distantFuture];
 85     self.nsTimerResume = YES;
 86     [[NSRunLoop currentRunLoop] addTimer:self.timerInN forMode:NSDefaultRunLoopMode];
 87     self.gcdTimerResume = YES;
 88 }
 89 
 90 -(void)changeImg
 91 {
 92     self.currentIndex ++;
 93     if (self.currentIndex > 75) {
 94         self.currentIndex = 1;
 95     }
 96     self.imgV.image = [UIImage imageNamed:[NSString stringWithFormat:@"%ld.jpg",self.currentIndex]];
 97 }
 98 
 99 -(void)CADisplayLinkAction
100 {
101     self.nsTimerResume = YES;
102     self.timerInN.fireDate = [NSDate distantFuture];
103     if (self.timerInG && !self.gcdTimerResume) {
104         dispatch_suspend(self.timerInG);
105         self.gcdTimerResume = YES;
106     }
107     self.timerInC.paused = !self.timerInC.paused;
108 }
109 
110 -(void)NSTimerAction
111 {
112     self.timerInC.paused = YES;
113     
114     if (self.timerInG && !self.gcdTimerResume) {
115         dispatch_suspend(self.timerInG);
116         self.gcdTimerResume = YES;
117     }
118     self.timerInN.fireDate = self.nsTimerResume?
119         [NSDate distantPast]:[NSDate distantFuture];
120     self.nsTimerResume = !self.nsTimerResume;
121 }
122 
123 -(void)GCDTimerAction
124 {
125     if (self.gcdTimerResume) {
126         self.timerInC.paused = YES;
127         self.nsTimerResume = YES;
128         self.timerInN.fireDate = [NSDate distantFuture];
129         static dispatch_once_t onceToken;
130         dispatch_once(&onceToken, ^{
131             self.timerInG = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
132             dispatch_source_set_timer(self.timerInG,  dispatch_walltime(NULL,0 * NSEC_PER_SEC), 0.032 * NSEC_PER_SEC, 0);
133             dispatch_source_set_event_handler(self.timerInG, ^{
134                 [self changeImg];
135             });
136         });
137         dispatch_resume(self.timerInG);
138     }
139     else
140     {
141         dispatch_suspend(self.timerInG);
142     }
143     self.gcdTimerResume = !self.gcdTimerResume;
144 }
145 
146 - (void)gotoRunloopAction
147 {
148     [self.timerInC invalidate];
149     self.timerInC = nil;
150     [self.timerInN invalidate];
151     self.timerInN = nil;
152     if (self.timerInG) {
153         if (self.gcdTimerResume) {
154             dispatch_resume(self.timerInG);
155         }
156         dispatch_source_cancel(self.timerInG);
157         self.timerInG = nil;
158     }
159     RunloopViewController * vc = [[RunloopViewController alloc] init];
160     [self.navigationController pushViewController:vc animated:YES];
161 }
162 - (void)didReceiveMemoryWarning {
163     [super didReceiveMemoryWarning];
164     // Dispose of any resources that can be recreated.
165 }
166 
167 @end