Singleton is a class that can only instantiate an object.
Although this is a practical definition of a singleton, it is not necessarily the case in the foundation framework. Like what
NsfilemangerAnd
Nsnotificationcenter,By their class method, respectively.
DefaultmanagerAnd
DefaultcenterGet. Although not strictly a single case, these class methods return a shared instance of a class that can be accessed in all code in the app. We will also use this approach in this article. The best way to use objective-c to implement singleton patterns has been a lot of controversy, and developers (including Apple) seem to change their minds every few years. When Apple introduced Grand Central Dispatch (GCD) (Mac OS 10.6 and iOS4.0), they also introduced a function that was well suited for implementing singleton patterns. The function is
dispatch_once:
void Dispatch_once (dispatch_once_t *predicate, dispatch_block_t block);
The function receives a
dispatch_onceA predicate that checks whether the code block has been dispatched (is a long integer, actually as
BOOLUse). It also receives a block of code that wants to be dispatched only once during the lifetime of the application, for this example is used for instantiation of a shared instance.
dispatch_onceNot only does it mean that the code will only be run once, but it's also thread-safe, which means you don't need to use things like
@synchronizedTo prevent problems that are not synchronized when using multiple threads or queues. Apple's GCD documentation confirms this:
if called by multiple threads, the function synchronizes and so on until the code block is complete.
How do you actually use these? Well, suppose there's a
Accountmanagerclass, you want to access the shared instance of the class throughout your app. You can implement a class method simply by following this code:
+ (Accountmanager *) Sharedmanager {
static Accountmanager *sharedaccountmanagerinstance = nil;
static dispatch_once_t predicate; Dispatch_once (&predicate, ^{
Sharedaccountmanagerinstance = [[Self alloc] init];
});
return sharedaccountmanagerinstance;
}
This means that any time you access a shared instance, you need to do just the following:
Accountmanager *accountmanager = [Accountmanager Sharedmanager];
In this case, you now have a shared instance in your app that will only be created once. There are a number of advantages to this approach: 1 Thread safety 2 good for static analyzer requirements 3 and automatic reference count (ARC) compatible 4 requires only a small amount of code the disadvantage of this approach is that it still runs to create a non-common Examples of benefits:
Accountmanager *accountmanager = [[Accountmanager alloc] init];
There are times when you want to have this behavior, but if you're looking for an instantiation of just one instance, you need to be aware of that.
Dispatch_once can guarantee that the code is executed once
+(NSDateFormatter*)Getdbdateformat{StaticNSDateFormatter* formatstatic dispatch_once_t oncetokendispatch_once (&oncetoken Span class= "o" >^{format = [[ Lkdateformatter alloc]init]format. DateFormat = @ "yyyy-mm-dd HH:mm:ss" ); return format;}
The description of dispatch_once_t is typedef long dispatch_once_t;
Description A predicate for use with the Dispatch_once function.
Dispatch_once unfold Yes
void_dispatch_once (dispatch_once_t *predicatedispatch_block_t Block) {if (dispatch_expect< Span class= "P" > (*predicate~0< span class= "n" >l) != ~0l ) {dispatch_once (predicateblock}} /span>
~0L is a long 0, which is a whole bunch of 1.
We'll expand Dispatch_expect, which is __builtin_expect ((x), (v))
__builtin_expect is the introduction of GCC (version>=2.9) macro, its role is to help the compiler to determine the expected value of the conditional jump, to avoid the jump caused by time confusion. has not changed its judgment on the truth.
So dispatch_once can be seen as
+(NSDateFormatter*)Getdbdateformat{StaticNSDateFormatter*Format;StaticLongOncetoken=0;if (oncetoken != 0 ) {1.{format = [[lkdateformatter span class= "n" >alloc]init]format. DateFormat = @ "yyyy-mm-dd HH:mm:ss" } 2.} return format;}
We can guess at the following 2 ... The code in the Oncetoken modifies the value of the
Output for a look,
+(NSDateFormatter*)Dateformatter{StaticNSDateFormatter*Format;Staticdispatch_once_tOncetoken;Nslogd(@"%ld",Oncetoken);Dispatch_once(&Oncetoken,^{nslogd (@ "%ld" oncetoken); format = [[nsdateformatter Alloc init]format. DateFormat = @ "yyyy-mm-dd HH:mm:ss" ); nslogd (@ "%ld" oncetoken); return format;}
The result is
0,
-1073755728,
-1
The discovery changed once in 1.
And then changed it in 2-1.
So it's easy to understand Dispatch_once's logic.
Objective-c Single case