根据您的解释,我知道即使您负责显示时间的视图控制器尚未初始化,您的计时器对象也应该继续工作,因此当应用程序第二次启动时,视图控制器将从计时器实例。
因此,我建议您创建一个单独的类来跟踪应用程序的状态(通过NSNotificationCenter 类)并处理您的计时器对象的重新初始化或失效。
这是描述上述逻辑的概念设计证明:
TimerManager.h
extern NSString * const TimerManagerDidCountDownNotification;
@interface TimerManager
@property (nonatomic, strong, readonly) NSTimer *timer;
@property (nonatomic, assign, readonly) CGFloat remainingTime;
+ (instancetype)sharedManager;
- (void)setCountDown:(CGFloat)countDown override:(BOOL)override;
@end
TimerManager.h
NSString * const TimerManagerDidCountDownNotification = @"TimerManagerDidCountDownNotification";
@interface TimerManager ()
@property (nonatomic, strong, readwrite) NSTimer *timer;
@property (nonatomic, assign, readwrite) CGFloat remainingTime;
@end
@implementation TimerManager
@synthesize remainingTime=_remainingTime;
- (instancetype)init
{
self = [super init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
return self;
}
+ (instancetype)sharedManager
{
static TimerManager *sharedManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedManager = [[self alloc] init];
});
return sharedManager;
}
- (void)didCountDown
{
if (self.remainingTime > 0.0) {
CGFloat newRemainingTime = self.remainingTime - 1.0;
[[NSNotificationCenter defaultCenter] postNotificationName:TimerManagerDidCountDownNotification object:nil userInfo:@{"remainingTime": @(newRemainingTime)}];
self.remainingTime = newRemainingTime;
}
else {
[_timer invalidate];
_timer = nil;
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"remaining_time"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
- (CGFloat)remainingTime
{
return [[NSUserDefaults standardUserDefaults] floatForKey:@"remaining_time"];
}
- (CGFloat)setRemainingTime:(CGFloat)remainingTime
{
[[NSUserDefaults standardUserDefaults] setFloat:remainingTime forKey:@"remaining_time"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (void)setCountDown:(CGFloat)countDown override:(BOOL)override
if (override || self.remainingTime == 0.0) {
[_timer invalidate];
self.remainingTime = countDown;
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(didCountDown) userInfo:nil repeats:YES];
}
}
- (void)applicationDidEnterBackground:(NSNotification *)notification
{
if (_timer) {
[_timer invalidate];
_timer = nil;
}
}
- (void)applicationWillEnterForeground:(NSNotification *)notification
{
if (!_timer) {
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(didCountDown) userInfo:nil repeats:YES];
}
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
在您的视图控制器类中,您可以覆盖 viewDidLoad 并将您的回调函数 (timerRun:) 注册到通知中心对象,以便从计时器中获取剩余时间:
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(timerRun:) name:TimerManagerDidCountDownNotification object:nil];
}
- (void)timerRun:(NSNotification *)notification
{
CGFloat secondCount = [notification[@"remainingTime"] floatValue];
int hours = (secondCount / 3600) % 24;
int minuts = (secondCount / 60) % 60;
int seconds = secondCount % 60;
NSString *timerOutput = [NSString stringWithFormat:@"%2d:%.2d:%2d", hours, minuts, seconds];
countdownLabel.text = timerOutput;
}
- (IBAction)start:(id)sender
{
[[TimerManager sharedManager setCountDown:82800.0 override:YES];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
您可以使用application:didFinishLaunchingWithOptions 方法作为起点,使用给定的countdown 值触发计时器。
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// some other initialization logic here...
[[TimerManager sharedManager] setCountDown:82800.0 override:NO];
return YES;
}