A small application using the timer, singleton and Protocol (2), Timer Protocol
In the previous article, I wrote a simple timer, which can also run properly. But now there is a problem, like the Timer Program on our mobile phone. Even when switching to the alarm clock or world time, the timer must still be running later. We can't do that just now. Because we have exited the timer interface when converting other interfaces, which means that the Controller of the interface has been destroyed. Our timer cannot still run when we switch to other interfaces. In this case, how can this problem be solved. We need to use a single-instance mode in many languages.
First, the most important question is what is the singleton mode. I checked a lot of information on the Internet and did not understand it very well. Now I want to explain my understanding. A singleton is a class with the same running cycle as a program. A program can only have one single-instance. You now have a controller. You instantiate a singleton in it. You modified the attribute value of this instance in this controller. Now there is another controller1. You continue to instantiate a singleton in this class. You can view the attribute value of this instance, and you will find that it is the same as the attribute value you modified just now. In addition, the life cycle of a single instance is the same as that of a program. Therefore, when you exit the interface, you will find that the timer is still running in the background.
Therefore, if we want to enable the timer to continue running after we exit the interface, we need to create a singleton class.
The following is the code for the singleton class.
Timemanager. h file
# Import <Foundation/Foundation. h>
# Import "Time. h"
@ Interface Timemanage: NSObject
@ Property (nonatomic, strong) Time * time;
+ (Timemanage *) shareManage; // The class initialization method of the singleton class. It is very important to determine whether your class is a singleton class.
-(Void) timestart;
-(Void) timepause;
@ End
Timemanage. m file
# Import "Timemanage. h"
@ Interface Timemanage ()
@ Property (nonatomic, retain) NSTimer * timer;
@ End
@ Implementation Timemanage
+ (Timemanage *) shareManage; // There are many initialization methods for a single instance, but this is officially recommended by Apple.
{
Static Timemanage * timemanageInstance = nil;
Static dispatch_once_t predicate;
Dispatch_once (& predicate, ^ {
TimemanageInstance = [[self alloc] init];
});
Return timemanageInstance;
}
-(Void) timestart
{
If (! _ Timer ){
_ Timer = [NSTimer scheduledTimerWithTimeInterval: 0.01f target: self selector: @ selector (UpdateUI) userInfo: nil repeats: YES];
}
}
-(Void) timepause
{
If (_ timer. valid ){
[_ Timer invalidate];
}
_ Timer = nil;
}
-(Void) UpdateUI
{
Self. time. ms ++;
[Self. time changtime];
// [Self. changedelegate changeUIwithtimestring: [self. time timestring]; The Protocol used
}
-(Time *) time
{
If (! _ Time ){
_ Time = [[Time alloc] init];
}
Return _ time;
}
@ End
The Singleton we want has been created successfully. But now the problem is how to synchronize our time to our UI in real time. We can initialize our NSTimer directly in the controller when we didn't use a singleton, and update our UI in real time in the UPdateUI method, but now we cannot directly reference lable. So here we must use the Protocol to ensure that our UI and data are synchronized.
First, modify our Timemanage. h file and create our protocol in this file.
# Import <Foundation/Foundation. h>
# Import "Time. h"
@ Protocol changeUIdelegate <NSObject>
-(Void) changeUIwithtimestring :( NSString *) time; // create a protocol
@ End
@ Interface Timemanage: NSObject
@ Property (nonatomic, strong) Time * time;
@ Property (nonatomic, retain) id <changeUIdelegate> changedelegate; // set the Protocol
+ (Timemanage *) shareManage;
-(Void) timestart;
-(Void) timepause;
@ End
Now you only need to add one sentence in Timemanage. m.
Modify the UpdateUI method.
-(Void) UpdateUI
{
Self. time. ms ++;
[Self. time changtime];
[Self. changedelegate changeUIwithtimestring: [self. time timestring]; // delegate. When this method is called, The viewcontroller Implementation Protocol method is also called.
}
Paste the viewcontroller code
# Import "ViewController. h"
# Import "Timemanage. h"
@ Interface ViewController () <changeUIdelegate> // declares that the Protocol is implemented.
@ Property (weak, nonatomic) IBOutlet UILabel * lable;
@ Property (strong, nonatomic) Timemanage * time;
@ End
@ Implementation ViewController
-(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.
}
-(IBAction) start :( id) sender {
_ Time = [Timemanage shareManage];
_ Time. changedelegate = self; // set the delegate object to itself
[_ Time timestart];
}
-(Void) changeUIwithtimestring :( NSString *) time
{
Self. lable. text = time; // The implementation of the protocol displays the passed time in lable.
}
-(IBAction) stop :( id) sender {
[_ Time timepause];
}
Now you can add viewtroller2, switch to another interface, and then switch to the timer page, you will find that the timer is still running.
The first time I wrote a blog, I was not very clear about many things. I hope to point it out.
@ End