如何解决Objective-C NSTimer,使用timeInterval 0.01更新UILabel导致应用程序冻结
#import "ActivityViewController.h"
@interface ActivityViewController ()
@property (weak,nonatomic) IBOutlet UIView *clockView;
@property (weak,nonatomic) NSTimer *timer;
@property (weak,nonatomic) IBOutlet UILabel *hoursLabel;
@property (weak,nonatomic) IBOutlet UILabel *minutesLabel;
@property (weak,nonatomic) IBOutlet UILabel *secondsLabel;
@property (weak,nonatomic) IBOutlet UILabel *miliLabel;
@end
@implementation ActivityViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
NSDate *start;
- (IBAction)pause:(UIButton *)sender {
[self.timer invalidate];
}
-(void)startTimer {
start = [[NSDate alloc] init];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(count) userInfo:nil repeats:true];
}
- (IBAction)startCounting:(UIButton *)sender {
[self startTimer];
}
-(void)count {
NSDate *Now = [[NSDate alloc] init];
NSTimeInterval interval = [Now timeIntervalSinceDate:start];
self.hoursLabel.text = [Nsstring stringWithFormat:@"%@",[self hourString:interval]];
self.minutesLabel.text = [Nsstring stringWithFormat:@"%@",[self minuteString:interval]];
self.secondsLabel.text = [Nsstring stringWithFormat:@"%@",[self secondString:interval]];
self.miliLabel.text = [Nsstring stringWithFormat:@"%@",[self miliString:interval]];
}
-(Nsstring *)hourString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long hours = (interval / 3600);
return [Nsstring stringWithFormat:@"%0.2ld",hours];
}
-(Nsstring *)minuteString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long minutes = (interval / 60) % 60;
return [Nsstring stringWithFormat:@"%0.2ld",minutes];
}
-(Nsstring *)secondString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long seconds = interval % 60;
return [Nsstring stringWithFormat:@"%0.2ld",seconds];
}
-(Nsstring *)miliString:(NSTimeInterval)timeInterval {
NSInteger ms = (fmod(timeInterval,1) * 100);
return [Nsstring stringWithFormat:@"%0.2ld",ms];
}
@end
这是视图控制器的整个实现
我尝试制作一个秒表,但是当我尝试在Objective-C中进行更新时(以毫秒为单位),它会在3秒后变慢,并在6秒后使模拟器和计算机模糊。有什么解决办法吗?迅速运行非常顺畅,但涉及到obj-c时我遇到了问题。
解决方法
几件事...您在主队列上调度,但是您已经在主队列中,因此您将淹没主队列。另外,您调度异步,以便队列很快就被阻塞。仍然我认为硬件应该能够实际处理它,因此我不完全确定为什么会死机,但是我认为您需要做得更好。
此外,重要的是,如果您制作了秒表,则不应该自己计算。当然,请使用计时器定期更新秒表,但您不应使用挂钟来代替自己计算时间。您现在的操作方式将非常不准确,并且随着时间的流逝,这些不准确会不断累积。
目前,您每10毫秒发射一次。也许每100触发一次,然后更新您的秒表,但从设备的内部时钟读取。这本身就是有问题的,有关如何执行此操作的一些想法,请参见How can I get the Correct Current Time in iOS?。
秒表开始时记下时间,例如
NSDate * start = NSDate.now;
,当计时器启动时,使用当前时间计算与该开始时间的差值,同样使用
NSDate * now = NSDate.now;
,并使用两者之间的差异更新秒表。这样会更轻松,更准确,但是请查看该链接,因为它也需要一些改进,并且只是目前的起点。
,我在最新的Xcode中创建了一个新的默认iOS项目,然后复制并粘贴并稍微固定了您的代码-参见下文。我只是将其连接到Xcode在项目中创建的默认视图控制器。
我正在人类已知的最古老的Mac mini上运行此程序,并在运行该项目时正在另一个项目上工作,这一点都没有遇到任何麻烦。查看屏幕截图。即使在5m之后,它仍然可以正常运行。我在其他地方继续工作没问题,没有任何变慢。我确定一定是其他有趣的问题吗?
library(stringr)
str_remove("(13) Miami (FL)","\\(\\d+\\)\\s+")
我敢肯定,这是另外一个问题……我假设您的#import "ViewController.h"
@interface ViewController ()
@property (weak,nonatomic) IBOutlet UIView * clockView;
@property (weak,nonatomic) IBOutlet UILabel * hoursLabel;
@property (weak,nonatomic) IBOutlet UILabel * minutesLabel;
@property (weak,nonatomic) IBOutlet UILabel * secondsLabel;
@property (weak,nonatomic) IBOutlet UILabel * miliLabel;
@property (strong,nonatomic) NSTimer * timer;
@property (strong,nonatomic) NSDate * start;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)pause:(UIButton *)sender
{
self.timer.invalidate;
}
-(void)startTimer
{
self.start = [[NSDate alloc] init];
self.timer.invalidate;
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.01
target:self
selector:@selector(count:)
userInfo:nil
repeats:true];
}
- (IBAction)startCounting:(UIButton *)sender
{
[self startTimer];
}
- ( void ) count:( NSTimer * ) timer
{
NSDate *now = [[NSDate alloc] init];
NSTimeInterval interval = [now timeIntervalSinceDate:self.start];
self.hoursLabel.text = [NSString stringWithFormat:@"%@",[self hourString:interval]];
self.minutesLabel.text = [NSString stringWithFormat:@"%@",[self minuteString:interval]];
self.secondsLabel.text = [NSString stringWithFormat:@"%@",[self secondString:interval]];
self.miliLabel.text = [NSString stringWithFormat:@"%@",[self miliString:interval]];
}
-(NSString *)hourString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long hours = (interval / 3600);
return [NSString stringWithFormat:@"%0.2ld",hours];
}
-(NSString *)minuteString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long minutes = (interval / 60) % 60;
return [NSString stringWithFormat:@"%0.2ld",minutes];
}
-(NSString *)secondString:(NSTimeInterval)timeInterval {
NSInteger interval = timeInterval;
long seconds = interval % 60;
return [NSString stringWithFormat:@"%0.2ld",seconds];
}
-(NSString *)miliString:(NSTimeInterval)timeInterval {
NSInteger ms = (fmod(timeInterval,1) * 100);
return [NSString stringWithFormat:@"%0.2ld",ms];
}
@end
只是从正常的ActivityViewController
派生而来的,而您的UIViewController
并没有做任何有趣的事情。
无论如何,看看是否有帮助,但我认为问题出在其他地方。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。