今天自己想完成一个类似于ios系统自带的计时器的功能。做的时候发现了很多问题,还好终于最后都一一解决了。
首先是NStimer类,这个类为我们提供了
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats类方法。
这个类能为我们创建一个在runloop中运行的定时器。我们来说一下上面方法的参数。seconds代表的一段时间,一段时间后自动执行selector的方法。target指的是那个方法所在的类。userinfo指的是定时器的具体的信息,我们可以把它设为nil。最后一个参数是一个bool值,如果是yes定时器会一直运行。如果是no,定时器运行一次之后便会停止。
这个类还有另外一个初始化方法:
+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
但是这个方法使用后,必须将定时器加入runloop。
还有个fire的方法,很多人可能会觉得这个方法是启动定时器。但是并不是这样的,经过试验还有看了一下苹果的官方文档。fire这个方法有两种情况,一种是定时器是循环的情况,也就是repeats参数为yes,你实现fire方法之后,会让selector里面的方法先执行一次,但是到了你设定的时间之后,会再次执行seletor当中的方法。另外一种也是repeats为no的情况,你执行fire方法之后会执行一次seletor中的方法,然后计时器就被销毁了。
下面我们来说一下怎么写一个简单的定时器。我们先来简直的写一个时间类,有几个简单的属性。
Time.h 文件
#import <Foundation/Foundation.h>
@interface Time : NSObject
@property(nonatomic) int ms;//0.01s.
@property(nonatomic) int seconds;
@property(nonatomic) int minutes;
@property(nonatomic) int hours;
-(id)initWith:(int)ms andseconds:(int)seconds andminutes:(int)minutes andhous:(int)hours;//创建一个新的初始化方法
-(NSString*)timestring;//转换成字符串,以00:00:00:00的格式显示
-(void)changtime;把由ms组成的时间转换成 由小时,分钟,秒,和ms组成的时间,也就是进位,100ms=1s 60s=1minute 60minute=1hour
@end
Time.m文件
#import "Time.h"
@implementation Time
-(id)initWith:(int)ms andseconds:(int)seconds andminutes:(int)minutes andhous:(int)hours
{
self=[super init];
if (self) {
self.ms=ms;
self.seconds=seconds;
self.minutes=minutes;
self.hours=hours;
}
return self;
}
-(NSString*) timestring
{
NSString *msstring;
NSString *minutesstring;
NSString *secondsstring;
NSString *hoursstring;
if (_ms<10) {
msstring=[NSString stringWithFormat:@"0%d",_ms];
}
else{
msstring=[NSString stringWithFormat:@"%d",_ms];
}
if (_seconds<10) {
secondsstring=[NSString stringWithFormat:@"0%d",_seconds];
}
else{
secondsstring=[NSString stringWithFormat:@"%d",_seconds];
}
if (_minutes<10) {
minutesstring=[NSString stringWithFormat:@"0%d",_minutes];
}
else{
minutesstring=[NSString stringWithFormat:@"%d",_minutes];
}
if (_hours<10){
hoursstring=[NSString stringWithFormat:@"0%d",_hours];
}
else{
hoursstring=[NSString stringWithFormat:@"%d",_hours];
}
NSString *timestring=[NSString stringWithFormat:@"%@:%@:%@:%@",hoursstring,minutesstring,secondsstring,msstring];
return timestring;
}
-(void)changtime
{
if (_ms>=100) {
_seconds++;
_ms=0;
}
if (_seconds>=60) {
_minutes++;
_seconds%=60;
}
if (_minutes>=60) {
_hours++;
_minutes%=60;
}
}
@end
这个类搞清楚方法是什么意思就行了,具体实现可以不管,主要是为了让时间的显示更为方便。
接下来让我们看下viewcontrollr中的方法
首先需要一个lable,然后是 两个button一个是开始按钮一个是暂停按钮。我用的是storyboard,先在storyboard里面拖一个lable和一个两个按钮。然后连接到controller当中。
ViewController.m文件
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *lable;
@property(nonatomic,retain) NSTimer *time;
@property(nonatomic,strong) Time *ltime;
@end
@implementation ViewController
// 按start调用这个方法
- (IBAction)start:(id)sender {
if(!_time)
{
_time=[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(UpdateUI:)userInfo:nil repeats:YES];
//创建一个定时器,每0.01s执行一次,设为循环
}
}
-(void)UpdateUI:(__unused NSTimer*)time //这个方法就是每0.01s执行一次的方法,让time的ms属性每0.01s自增一次
{
++self.ltime.ms;
[self.ltime changtime];
self.lable.text=[self.ltime timestring];
}
按stop键调用的方法
-(IBAction)stop:(id)sender {
//valid是那是nstimer的一个属性,判断定时器是否正在运行
if (_time.valid){
[_time invalidate];
_time=nil;
}
}
-(Time*)ltime
{
if (!_ltime) {
_ltime=[[Time alloc]init];
}
return _ltime;
}
都是自己的一些理解,有什么不对请指出,谢谢。