Ios 目标C-使用单例的不间断定时器

Ios 目标C-使用单例的不间断定时器,ios,objective-c,uiviewcontroller,timer,singleton,Ios,Objective C,Uiviewcontroller,Timer,Singleton,我的应用程序由3个视图控制器组成ViewController1由一些标签和按钮组成,用户试图在这些标签和按钮上解决问题并按下按钮。按钮将他们带到ViewController2,在那里显示他们的统计信息(精度、时间等)。然后,该应用程序会在2秒钟后自动将用户导航回游戏。这个过程持续2分钟。2分钟结束后,我希望应用程序导航到ViewController3(主菜单) 我正在尝试实现一个计时器,即使在视图控制器之间切换时,它也能继续工作。我(在stackoverflow的帮助下)实现了一个具有计时器属性

我的应用程序由3个视图控制器组成
ViewController
1由一些标签和按钮组成,用户试图在这些标签和按钮上解决问题并按下按钮。按钮将他们带到
ViewController
2,在那里显示他们的统计信息(精度、时间等)。然后,该应用程序会在2秒钟后自动将用户导航回游戏。这个过程持续2分钟。2分钟结束后,我希望应用程序导航到
ViewController
3(主菜单)

我正在尝试实现一个
计时器
,即使在视图控制器之间切换时,它也能继续工作。我(在stackoverflow的帮助下)实现了一个具有计时器属性的
单例类。但是,它没有按要求运行。我已经试着打印出值(在代码中注释)来查看发生了什么,但是运气不好

这是我的密码:

ApplicationManager.m

    //
    //  ApplicationManager.m

    #import <Foundation/Foundation.h>

    #import "ApplicationManager.h"


    @implementation ApplicationManager

    static ApplicationManager* appMgr = nil;

    +(ApplicationManager*)instance{
        @synchronized ([ApplicationManager class]){
            if (!appMgr) {
                appMgr = [[self alloc]init];
            }

            return appMgr;

        }

        return nil;

    }

    +(id) alloc{

        @synchronized([ApplicationManager class]){
            NSAssert((appMgr == nil), @"Only one instance of singleton class may be instantiated");
            appMgr = [super alloc];
            return appMgr;


        }
    }

    +(id) init{
        if (!(self == [super init])) {
            return nil;
        }
        return self;
    }


    @end
ViewController.m

#import "ViewController.h"

#import "ApplicationManager.h"

NSString* const MAXTRIALTIME = @"00:50.000"; //50 Seconds just for testing purposes

@implementation ViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    [[ApplicationManager instance]setstartDate:[NSDate date]];

    [self startTimer];

//other functionalities 

}

-(void)startTimer{

    [[ApplicationManager instance] setTimer:[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTimer) userInfo:nil repeats:YES]];

}

-(void) resetTimer{
    [[[ApplicationManager instance] timer]invalidate];
}

-(void)updateTimer{
    NSDate *currentTime = [NSDate date];
    NSLog(@"Start Date2: %@", [[ApplicationManager instance]startDate]); //PRINTS (null)

    NSTimeInterval timerInterval = [currentTime timeIntervalSinceDate:[[ApplicationManager instance]startDate]];

    NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timerInterval];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"mm:ss.SSS"];

    [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];

    self.finalTime = [dateFormatter stringFromDate:timerDate];

    NSLog(@"Time: %@\n",self.finalTime); //PRINTS random numbers

    if ([self.finalTime isEqualToString:MAXTRIALTIME]) {
        [self resetTimer];
       //move to a different view controller

    }

}

@end
ViewController.h

extern NSString* const MAXTRIALTIME;
@property (strong, nonatomic) NSString *finalTime;
//other declarations 

在ApplicationController单例类中,您正在实例方法中调用self。任何实例化类的方法(即以+开头的方法)都不应该引用self,因为self在该点上不存在

您需要执行以下操作:

if (!appMgr) {
    appMgr = [[ApplicationManager alloc] init];
}
这就是打印startDate属性时变为NULL的原因

此外,ApplicationManager singleton是其计时器属性的所有者,因此需要(强)计时器属性。弱属性用于引用其他类所拥有的对象。看看ARC的东西

最后,init方法应该是-method而不是+1,只要您只使用instance方法访问ApplicationManager,就不需要重写alloc方法。如果我是你,我会完全放弃alloc和init方法,只使用实例方法

if (!appMgr) {
    appMgr = [[ApplicationManager alloc] init];
}