NSTimer 仅在模拟器上无法在 StopWatch 应用程序上运行(显示静态奇怪数字)

Posted

技术标签:

【中文标题】NSTimer 仅在模拟器上无法在 StopWatch 应用程序上运行(显示静态奇怪数字)【英文标题】:NSTimer not working on StopWatch App ONLY ON SIMULATOR (Shows static strange number) 【发布时间】:2012-03-29 13:08:23 【问题描述】:

当我点击 Start 时,stopWatchLabel 显示以下内容(它是静态的,没有运行):

注意:当我在我的 iPhone 上测试这个应用程序时,一切都按预期运行。完全没有问题。

谁能解释一下原因?

.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

    NSTimer *stopWatchTimer; 
    NSDate *startDate;



@property (strong, nonatomic) IBOutlet UILabel *stopWatchLabel;

- (IBAction)startButtonTapped:(id)sender;

- (IBAction)stopButtonTapped:(id)sender;

-(void)updateTimer;

@end

.m

- (IBAction)startButtonTapped:(id)sender 

    stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 
                                                      target:self 
                                                    selector:@selector(updateTimer) 
                                                    userInfo:nil 
                                                     repeats:YES];



- (void)updateTimer

    NSDate *currentDate = [NSDate date];
    NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];
    NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"HH:mm"];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];

    NSString *timeString=[dateFormatter stringFromDate:timerDate];
    stopWatchLabel.text = timeString;



- (IBAction)stopButtonTapped:(id)sender 

    [stopWatchTimer invalidate];

【问题讨论】:

请参阅here 以直接从NSTimeInterval 获取小时和分钟。无需创建新日期并对其进行格式化。 【参考方案1】:

你没有设置startDate

您的代码应如下所示(我假设这是 ARC):

- (IBAction)startButtonTapped:(id)sender 
    startDate = [NSDate date];

    stopWatchTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 
                                                      target:self 
                                                    selector:@selector(updateTimer) 
                                                    userInfo:nil 
                                                     repeats:YES];

updateTimer 是一种将秒分为分钟和秒的荒谬复杂的方法。做一些基本的数学运算。

- (void)updateTimer

    NSDate *currentDate = [NSDate date];
    NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:startDate];

    NSInteger minutes = floor(timeInterval/60);
    NSInteger seconds = trunc(timeInterval - minutes * 60);

    NSString *timeString=[NSString stringWithFormat:@"%i:%02i", minutes, seconds];
    stopWatchLabel.text = timeString;


编辑:实际上您应该使用内置的 NSCalendar/NSDateComponents API,因为它不会像基本数学方法那样忽略夏令时。

- (void)updateTimer

    NSDate *currentDate = [NSDate date];
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [calendar components:NSSecondCalendarUnit|NSMinuteCalendarUnit fromDate:startDate toDate:currentDate options:0];
    NSInteger minutes = [components minute];
    NSInteger seconds = [components second];

    NSString *timeString=[NSString stringWithFormat:@"%i:%02i", minutes, seconds];
    stopWatchLabel.text = timeString;
 

【讨论】:

谢谢马蒂亚斯。再次感谢您的帮助。

以上是关于NSTimer 仅在模拟器上无法在 StopWatch 应用程序上运行(显示静态奇怪数字)的主要内容,如果未能解决你的问题,请参考以下文章

仅在物理设备而非模拟器上运行 Android 应用程序

在后台运行 NSTimer 方法

核心数据:“无法在此模型中找到名为 ... 的实体”(仅在设备上)

仅在某些设备上出现核心数据标量错误

Flutter 无法仅在物理 iOs 设备中构建和运行 iOS 应用程序

仅在 Pixel_Api_26 模拟器中从相机拍摄照片后,无法在 ImageView 中放置图像