Сохранение таймера, работающего на другой странице, при перемещении по ней


Я пытаюсь поддерживать таймер, работающий на другой странице, когда вы переключаетесь на другие страницы и выполняете другие задачи, по сути, сохраняя часы на том, сколько времени требуется для выполнения задач. Всякий раз, когда я переключаюсь на другую страницу, он сбрасывает таймер обратно на то, что он был запущен, и делает то же самое с некоторыми переключателями на других страницах, которые я пытаюсь сохранить. Есть идеи?

Скриншот раскадровки:

Код до сих пор:

//
//  ViewController.m


#import "ViewController.h"

@interface ViewController ()


@end

@implementation ViewController

- (IBAction)start{
ticker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self    ``selector:@selector(showActivity) userInfo:nil repeats:YES];

}

- (IBAction)reset{
[ticker invalidate];
time.text = @" 0:00";
}

- (void)showActivity{
int currentTime = [time.text intValue];
int newTime = currentTime + 1;
time.text = [NSString stringWithFormat:@"%d", newTime];
}




- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end

//  ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController{

IBOutlet UILabel *time;
NSTimer *ticker;
}

- (IBAction)start;
- (IBAction)reset;


- (void)showActivity;
@end
1 2

1 ответ:

Ваш NSTimer является переменной-членом класса контроллера вида. Я предполагаю, что при переключении между видами вы уничтожаете этот контроллер вида и создаете экземпляр нового. Это означает, что этот контроллер вида исчез, а также таймер; это не то, что таймер сбрасывается, это то, что ваш старый таймер был уничтожен, а новый создается.

Что вам нужно, так это хранить ваш NSTimer и его функциональность в месте, где он не будет уничтожен каждый раз, когда вы меняете контроллер вида. Одним из решений является создание синглетного класса, который обрабатывает таймер. (Одноэлементный класс-это класс, который может быть создан только один раз; может существовать только один его экземпляр. Подробнее о них можно прочитать здесь.)

Вот пример того, как можно создать одноэлементный класс в Objective-C. заголовок:

//ApplicationManager.h

@interface ApplicationManager : NSObject

+(ApplicationManager*) instance;

@end

И реализация:

//ApplicationManager.m

#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]))
    {
        [self release];
        return nil;
    }

    return self;
}

@end

При первом вызове метода instance экземпляр Будет создан ApplicationManager. Каждый раз, когда вы хотите получить к нему доступ, снова вызывайте метод instance; ApplicationManager будет возвращен. Теперь вы просто добавляете свой NSTimer (и любой другой объект, который вы хотите сохранить в вашем приложении) в качестве переменных-членов класса ApplicationManager.

Затем необходимо импортировать класс ApplicationManager в класс контроллера вида, и методы контроллера вида изменятся на:

-(IBAction) start
{
    [[ApplicationManager instance] setTicker:[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(showActivity) userInfo:nil repeats:YES]];
}

-(IBAction) reset
{
    [[[ApplicationManager instance] ticker] invalidate];
    time.text = @" 0:00";
}

-(void) showActivity
{
    int currentTime = [time.text intValue];
    int newTime = currentTime + 1;
    time.text = [NSString stringWithFormat:@"%d", newTime];
}

Если вы хотите, чтобы все было хорошо и аккуратно, вы также можете добавить эту строку в начало класса ApplicationManager:

#define APPMGR [ApplicationManager instance]
Теперь вместо того, чтобы вводить [ApplicationManager instance] везде, вы можете просто ссылаться на него как на APPMGR. [APPMGR ticker] намного чище, чем [[ApplicationManager instance] ticker] :)