ios - Objective C - 使用 Singleton 的不间断计时器

标签 ios objective-c uiviewcontroller timer singleton

我的应用程序包含 3 个 ViewControllersViewController1 由一些标签和按钮组成,用户可以在其中尝试解决问题并按下按钮。该按钮会将它们带到 ViewController 2,在那里会显示它们的统计信息(准确性、时间等)。然后,该应用会在 2 秒后自动将用户导航回游戏。此过程持续 2 分钟。 2 分钟后,我希望应用导航到 ViewController 3(主菜单)。

我正在尝试实现一个 timer,它即使在 View Controller 之间切换时也能保持运行。我已经(在 stackoverflow 的帮助下)实现了一个具有计时器属性的 singleton class。但是,它没有按要求运行。我尝试打印出值(在代码中注释)以查看发生了什么,但没有成功。

这是我的代码:

应用程序管理器.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

应用管理器.h

    @interface ApplicationManager : NSObject
    +(ApplicationManager*) instance;

    @property(weak, nonatomic) NSTimer* timer;
    @property(weak, nonatomic) NSDate* startDate;


    @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 单例是其计时器属性的所有者,因此需要(强)。弱属性用于引用其他类拥有的对象。检查 ARC 的东西。

最后,init 方法应该是一个 - 方法而不是一个 + 方法,并且只要您只使用实例方法访问您的 ApplicationManager,您就不需要重写 alloc 方法。如果我是你,我会完全摆脱 alloc 和 init 方法,只使用实例之一。

关于ios - Objective C - 使用 Singleton 的不间断计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26360156/

相关文章:

ios - 使用 Alamofire 4.0 进行参数编码时出现问题

ios - UIImagePickerController 选择图像 IOS 7

iPhone 编程 - 在 View Controller 之间传递 NSMutableArray

ipad - 当键盘出现在带有 iOS8 的 iPad 上时,将模态呈现的 UIViewController 向上移动

ios - Xcode 快速删除按钮

iphone - 停止 NSTimer 不断增加间隔

iphone - 不正确的签名错误

部署后 iOS 共享扩展不起作用

ios - ARC block ,弱和保留计数

iphone - UIViewController 旋转方法