Keeping a timer running on another page when navigating around

跟風遠走 提交于 2019-12-06 07:40:10

Your NSTimer is a member variable of your view controller class. I'm assuming that when you switch between views, you're destroying this view controller and instantiating an instance of a new one. That means this view controller is gone, as well as the timer; it's not that the timer is being reset, it's that your old timer has been destroyed an a new one is being created.

What you need is to store your NSTimer and its functionality in a place where it will not be destroyed every time you change your view controller. One solution is to create a Singleton class which handles the timer. (A Singleton class is a class that can only be created one time; only one instance of it can exist. You can read more about them here.)

Here is an example of how you can create a Singleton class in Objective-C. The header:

//ApplicationManager.h

@interface ApplicationManager : NSObject

+(ApplicationManager*) instance;

@end

And the implementation:

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

The first time you call the instance method, the instance of the ApplicationManager will be created. Each time you want to access it, call the instance method again; the ApplicationManager will be returned. Now you simply add your NSTimer (and any other object you wish to persist throughout your application) as member variables of the ApplicationManager class.

You then must import the ApplicationManager class into your view controller class, and your view controller methods will change to:

-(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];
}

If you want to make things nice and neat, you can also add this line to the top of your ApplicationManager class:

#define APPMGR [ApplicationManager instance]

Now instead of having to type [ApplicationManager instance] everywhere, you can simply refer to it as APPMGR instead. [APPMGR ticker] is a lot cleaner than [[ApplicationManager instance] ticker] :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!