技術(shù)遷移:http://blog.csdn.net/iosbird/article/details/76360049
我在工程中寫了一個方法
-
(void)timecount{
NSDate* date = [NSDate date];
NSDateFormatter formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"hh:mm:ss"];
NSString time = [formatter stringFromDate:date];
NSLog(@"%@",time);
}
用于打印時間字符串的
首先定義一個變量
NSTimer _timer;
然后實現(xiàn)計時器功能
利用NSTimer*
方法1雌芽、創(chuàng)建并綁定計時器
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timecount) userInfo:nil repeats:YES];
效果如下:
方法2棚蓄、
_timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timecount) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSDefaultRunLoopMode];
注意,上面的runloop是在主線程中開啟的信夫,要在子線程開啟仿野,就需要手動開啟了
方法3铣减、子線程中開啟runloop
[NSThread detachNewThreadSelector:@selector(useNSTimer) toTarget:self withObject:nil];
實現(xiàn)方法useNSTimer (void)useNSTimer{
_timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timecount) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSRunLoopCommonModes];
// runloop在子線程上是需要手動開啟的
[[NSRunLoop currentRunLoop] run];
}
如果要銷毀子線程中的定時器,就要在子線程中調(diào)用銷毀方法,否則會造成runloop資源的浪費-
(void)useNSTimer{
_timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(timecount) userInfo:nil repeats:YES];
[self performSelector:@selector(stopcount) withObject:nil afterDelay:10];
[[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSRunLoopCommonModes];
//// runloop在子線程上是需要手動開啟的
[[NSRunLoop currentRunLoop] run];
}
上面的代碼就是在10秒后銷毀定時器 -
(void)stopcount{
[_timer invalidate];
_timer = nil;
}
效果圖如下:
注意脚作,runloop對timer有了強引用葫哗,weak型的timer不會被釋放,所以要在適當(dāng)?shù)臅r候銷毀timer對象
上面的timer都會造成循環(huán)引用,我們可以給NSTimer擴展一個方法:
定義并實現(xiàn)
- (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval block:(void (^)())block repeats:(BOOL)repeats{
return [NSTimer timerWithTimeInterval:interval target:self selector:@selector(timerSelector:) userInfo:block repeats:repeats];
} - (void)timerSelector:(NSTimer *)timer{
void (^ block)() =[timer userInfo];
if (block) {
block();
}
}
在調(diào)用時倒入我們寫的擴展
__weak typeof(self)weakSelf = self;
_timer = [NSTimer timerWithTimeInterval:1 block:^{
[weakSelf timecount];
} repeats:YES];
[[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSRunLoopCommonModes];
[[NSRunLoop currentRunLoop] run];
如此就避免了timer帶來的循環(huán)引用問題
在iOS10以后,蘋果提供了帶block的方法就避免了循環(huán)引用
_timer = [NSTimer timerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
}];
[[NSRunLoop currentRunLoop]addTimer:_timer forMode:NSRunLoopCommonModes];
或者
_timer = [NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
}];
利用GCD實現(xiàn)計時器
- (void)usegcd:(NSTimeInterval)timeinterval repeats:(BOOL)repeats{
__weak typeof(self)weakSelf = self;
dispatch_queue_t queue = dispatch_queue_create("計時器", 0);
dispatch_source_t time = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(time, DISPATCH_TIME_NOW, NSEC_PER_SEC, 0);
dispatch_source_set_event_handler(time, ^{
if (!repeats) {
dispatch_cancel(time);
}
else
[weakSelf timecount];
});
dispatch_resume(time);
}