解决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

你可能感兴趣的:(#,IPhone开发高级系列)