Цель C - Бесперебойный таймер с использованием Singleton

Мое приложение состоит из 3 ViewControllers. ViewController 1 состоит из нескольких меток и кнопок, где пользователь пытается решить проблему и нажимает кнопку. Кнопка переводит их в ViewController 2, где им показывают свою статистику (точность, время и т.д.). Затем приложение автоматически переводит пользователя обратно в игру через 2 секунды. Этот процесс продолжается 2 минуты. По истечении 2 минут я хочу, чтобы приложение переходило к ViewController 3 (Главное меню).

Я пытаюсь реализовать timer, который продолжает работать даже при переключении между диспетчерами. Я реализовал (с помощью stackoverflow) singleton class, обладающий свойством таймера. Однако он не работает по мере необходимости. Я попробовал распечатать значения (прокомментированные в коде), чтобы узнать, что происходит, но не повезло.

Вот мой код:

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
</foundation>

ApplicationManager.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
1 ответ

В вашем одиночном классе ApplicationController вы вызываете вызов self в методе экземпляра. Любые методы, которые создают экземпляр класса (т.е. Методы, начинающиеся с символа +), никогда не должны ссылаться на себя, поскольку в этой точке самость не будет существовать.

Вам нужно сделать:

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

Именно по этой причине вы получаете NULL при печати свойства startDate.

Кроме того, SingleManager ApplicationManager является владельцем его свойства таймера, поэтому он должен быть (сильным). Слабые свойства - это ссылки на объекты, принадлежащие другим классам. Просмотрите материал ARC.

Наконец, метод init должен быть a - method not a + one, и вам не нужно переопределять метод alloc, если вы используете метод экземпляра только для доступа к вашему ApplicationManager. Если бы я был вами, я бы полностью избавился от методов alloc и init и просто использовал экземпляр.

licensed under cc by-sa 3.0 with attribution.