首页 > 代码库 > 解决iOS程序UI主线程和定时器相互阻塞的问题
解决iOS程序UI主线程和定时器相互阻塞的问题
我的问题是这样,我的页面上有一个UIScrollView和一个定时器用来记录当前考试模式下的剩余时间,问题出现了:当我滑动滚动试图时,定时器的方法便不在运行(即被UI主线程阻塞)。google一下找到了解决办法:将定时器放在非主线程中执行将更新UI的操作放到主线程,这样UI主线程和定时器就能互不干扰的相互工作了。
在另一个项目中,还解决了一个问题:手机验证码,获取按钮,点击获取后,会开始倒计时一段时间,按钮不可点,按钮上的文字不断变化。
获取验证码 |
120秒后重新获取 |
119秒后重新获取 |
以下是主要代码:
1 #import "CountdownTool.h" 2 3 @interface CountdownTool() 4 { 5 UILabel *_lblShow; 6 NSTimer *_timer; 7 } 8 @property (nonatomic, assign) NSInteger hour; 9 @property (nonatomic, assign) NSInteger minute; 10 @property (nonatomic, assign) NSInteger second; 11 @property (nonatomic, copy) NSString *strHour; 12 @property (nonatomic, copy) NSString *strMinute; 13 @property (nonatomic, copy) NSString *strSecond; 14 @property (nonatomic, assign) NSInteger totalSeconds; 15 @end 16 @implementation CountdownTool 17 @synthesize hour = _hour; 18 @synthesize minute = _minute; 19 @synthesize second = _second; 20 @synthesize totalSeconds = _totalSeconds; 21 22 - (void)dealloc 23 { 24 [_lblShow release]; 25 [_strHour release]; 26 [_strMinute release]; 27 [_strSecond release]; 28 [super dealloc]; 29 } 30 31 - (id)initWithFrame:(CGRect)frame 32 { 33 self = [super initWithFrame:frame]; 34 if (self) { 35 _lblShow = [[UILabel alloc] initWithFrame:self.bounds]; 36 _lblShow.backgroundColor = [UIColor clearColor]; 37 _lblShow.font = [UIFont systemFontOfSize:15]; 38 _lblShow.textColor = [UIColor yellowColor]; 39 _lblShow.textAlignment = NSTextAlignmentCenter; 40 _lblShow.numberOfLines = 1; 41 [self addSubview:_lblShow]; 42 } 43 return self; 44 } 45 46 - (id)initWithFrame:(CGRect)frame andMinutesNum:(NSInteger)minute 47 { 48 if (self = [self initWithFrame:frame]) { 49 self.totalSeconds = minute * 60; 50 //多线程启动定时器 51 [NSThread detachNewThreadSelector:@selector(startTimer) toTarget:self withObject:nil]; 52 } 53 return self; 54 } 55 - (void)startTimer 56 { 57 _timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerFire) userInfo:nil repeats:YES]; 58 [[NSRunLoop currentRunLoop] run]; 59 } 60 - (void)handleWithTotalSeconds 61 { 62 self.hour = _totalSeconds/3600; 63 self.minute = _totalSeconds%3600/60; 64 self.second = _totalSeconds%3600%60; 65 if (_hour <= 0) { 66 _lblShow.text = [NSString stringWithFormat:@"%@:%@",_strMinute,_strSecond]; 67 }else{ 68 _lblShow.text = [NSString stringWithFormat:@"%@:%@:%@",_strHour,_strMinute,_strSecond]; 69 } 70 } 71 - (void)setHour:(NSInteger)hour 72 { 73 _hour = hour; 74 if (_hour < 10) { 75 self.strHour = [NSString stringWithFormat:@"0%d",_hour]; 76 }else{ 77 self.strHour = [NSString stringWithFormat:@"%d",_hour]; 78 } 79 } 80 - (void)setMinute:(NSInteger)minute 81 { 82 _minute = minute; 83 if (_minute < 10) { 84 self.strMinute = [NSString stringWithFormat:@"0%d",_minute]; 85 }else{ 86 self.strMinute = [NSString stringWithFormat:@"%d",_minute]; 87 } 88 } 89 - (void)setSecond:(NSInteger)second 90 { 91 _second = second; 92 if (_second < 10) { 93 self.strSecond = [NSString stringWithFormat:@"0%d",_second]; 94 }else{ 95 self.strSecond = [NSString stringWithFormat:@"%d",_second]; 96 } 97 } 98 - (void)setTotalSeconds:(NSInteger)totalSeconds 99 { 100 _totalSeconds = totalSeconds; 101 [self performSelectorOnMainThread:@selector(handleWithTotalSeconds) withObject:nil waitUntilDone:YES]; 102 } 103 - (void)timerFire 104 { 105 if (_totalSeconds == 0) { 106 [_timer invalidate]; 107 return; 108 } 109 self.totalSeconds -= 1; 110 } 111 @end
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。