ios 中定时器:NSTimer, CADisplayLink, GCD
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