如何使用dispatch_once创建单例模式

发布网友

我来回答

1个回答

热心网友

Wikipedia defines it as:In software engineering, the singleton pattern is a design pattern used to implement the mathematical concept of a singleton, by restricting the instantiation of a class to one object.Or as I would put it:A singleton is a class, where only one instance of it can instantiated.Although this is the actual definition of a singleton, this isn’t always the case in the world of Foundation. NSFileManger and NSNotificationCenter for example, are usually accessed through their class methods defaultManager and defaultCenter respectively. Although not strictly a singleton, these class methods return a shared instance of that class that developers can then access throughout their code. It is this approach that we will be looking at in this post.There has always been a debate(辩论) on the best way to implement the singleton pattern using Objective-C, and developers (including Apple) seem to have been changing their minds every couple of years. When Apple introced Grand Central Dispatch (GCD) (in Mac OS 10.6 and iOS 4.0) they introced a function that is perfect for implementing the singleton pattern.this function is dispatch_once:void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);This function takes a predicate (which is a long, that in reality acts as a BOOL) that the dispatch_once function uses to check if the block has already been dispatched. It also takes the block that you wish to only be dispatched once for the lifetime of the application, for us this is the instantiation of our shared instance.(用GCD里面的dispatch_once函数来实现单例,它接受一个dispatch_once_t和一个block参数,前者用来标识block是否有被执行过,必须是static或global的。dispatch_once可以保证block仅被执行一次。)
Well lets say you have a Account Manager class, and you want to access a shared instance of this class throughout your application, you can simply implement a class method like the one below:+ (AccountManager *)sharedManager{static AccountManager *sharedAccountManagerInstance = nil;static dispatch_once_t predicate;dispatch_once(&predicate, ^{sharedAccountManagerInstance = [[self alloc] init];});return sharedAccountManagerInstance;}This means whenever you want access this shared instance all you need to do is:AccountManager *accountManager = [AccountManager sharedManager];And that’s all there is to it, you now have a shared instance that you can access throughout your application, which will only be created once.This approach has many advantages:It is thread safeIt will keep the static analyser happyIt is compatible with Automatic Reference Counting (ARC)It only requires a small amount of codeThe only disadvantage with this approach is that it will still allow a non shared instance to be created:AccountManager *accountManager =[[AccountManager alloc] init];Sometimes you will actually want this behaviour, but it is something you need to be aware of when you really only want one instance of a class to ever be instantiated.

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com