IOS Singleton mode dispatch_once
IOS Singleton mode dispatch_once
Some variables only need to be initialized once (for example, reading configuration parameters from the file, reading the device model, and so on). You can use dispatch_once for read optimization to ensure that only the API is called once, in the future, you only need to directly access the variable.
WeatherClient. h
# Import "AFHTTPClient. h"
@ Interface WeatherClient: AFHTTPClient
+ (WeatherClient *) sharedClient;
@ End
WeatherClient. m
# Import "WeatherClient. h"
@ Implementation WeatherClient
+ (WeatherClient *) sharedClient
{
Static WeatherClient * sharedClient = nil;
Static dispatch_once_t onceToken;
Dispatch_once (& onceToken, ^ {sharedClient = [[WeatherClient alloc] initWithBaseURL: [NSURL URLWithString: API];
});
Return sharedClient;
}
@ End
In software engineering, Singleton is a mathematical concept used to implement Singleton, which limits the instantiation of classes to a design pattern of only one object.
Or, my understanding is:
A singleton is a type that can only instantiate one object.
Although this is the actual definition of a Singleton, it is not necessarily the case in the Foundation framework. For example, NSFileManger and NSNotificationCenter are obtained through their class methods defaultManager and defacenter center respectively. Although it is not a strict Singleton, these class methods return a shared instance of classes that can be accessed in all the code of the application. This method will also be used in this article. There has always been a lot of debate over the best way to use Objective-C to implement the singleton model, and developers (including Apple) seem to change their thinking every few years. When Apple introduced Grand Central Dispatch (GCD) (Mac OS 10.6 and iOS4.0), they also introduced a function that is suitable for implementing the singleton mode. This function is dispatch_once:
Void dispatch_once (dispatch_once_t * predicate, dispatch_block_t block );
This function receives a dispatch_once predicate used to check whether the code block has been scheduled (a long integer, actually used as a BOOL ). It also receives a code block that only needs to be scheduled once in the life cycle of the application. This example is used for instantiation of the shared instance. Dispatch_once not only means that the Code will be run only once, but also thread-safe, this means that you do not need to use such as @ synchronized to prevent non-synchronization when multiple threads or queues are used. Apple's GCD Documentation confirms this:
If called by multiple threads, the function is synchronized until the code block is complete.
How do I actually use this? Well, suppose there is an AccountManager class, and you want to access the shared instance of this class in the whole application. You can simply implement a class method using the following code:
+ (AccountManager *) sharedManager {
Static AccountManager * sharedAccountManagerInstance = nil;
Static dispatch_once_t predicate;
Dispatch_once (& predicate, ^ {
SharedAccountManagerInstance = [[self alloc] init];
});
Return sharedAccountManagerInstance;
}
This means that you can access the shared instance at any time. The only thing you need to do is:
AccountManager * accountManager = [AccountManager sharedManager];
In this case, you now have a shared instance in the application, which is created only once. This method has many advantages:
1 thread security 2 Good to meet static analyzer requirements 3 compatible with automatic reference count (ARC)
4. The disadvantage of this method is that it still runs to create a non-shared instance:
AccountManager * accountManager = [[AccountManager alloc] init];
Sometimes you want this kind of behavior, but if you want only one instance to be instantiated, you need to pay attention to this.