Creating a Singleton Instance 不及格的程序员

Creating a Singleton Instance

Some classes of the Foundation and AppKit frameworks create singleton objects. In a strict implementation, a singleton is the sole allowable instance of a class in the current process. But you can also have a more flexible singleton implementation in which a factory method always returns the same instance, but you can allocate and initialize additional instances.The NSFileManager class fits this latter pattern, whereas theUIApplication fits the former. When you ask for an instance of UIApplication, it passes you a reference to the sole instance, allocating and initializing it if it doesn’t yet exist.

A singleton object acts as a kind of control center, directing or coordinating the services of the class. Your class should generate a singleton instance rather than multiple instances when there is conceptually only one instance (as with, for example, NSWorkspace). You use singleton instances rather than factory methods or functions when it is conceivable that there might be multiple instances someday.

To create a singleton as the sole allowable instance of a class in the current process, you need to have an implementation similar to Listing 2-15. This code does the following:

  • It declares a static instance of your singleton object and initializes it to nil.

  • In your class factory method for the class (named something like “sharedInstance” or “sharedManager”), it generates an instance of the class but only if the static instance is nil.

  • It overrides the allocWithZone: method to ensure that another instance is not allocated if someone tries to allocate and initialize an instance of your class directly instead of using the class factory method. Instead, it just returns the shared object.

  • It implements the base protocol methods copyWithZone:releaseretainretainCount, and autorelease to do the appropriate things to ensure singleton status. (The last four of these methods apply to memory-managed code, not to garbage-collected code.)

Listing 2-15  Strict implementation of a singleton

 1 static MyGizmoClass *sharedGizmoManager = nil;
 2  
 3 + (MyGizmoClass*)sharedManager
 4 {
 5     if (sharedGizmoManager == nil) {
 6         sharedGizmoManager = [[super allocWithZone:NULL] init];
 7     }
 8     return sharedGizmoManager;
 9 }
10  
11 + (id)allocWithZone:(NSZone *)zone
12 {
13     return [[self sharedManager] retain];
14 }
15  
16 - (id)copyWithZone:(NSZone *)zone
17 {
18     return self;
19 }
20  
21 - (id)retain
22 {
23     return self;
24 }
25  
26 - (NSUInteger)retainCount
27 {
28     return NSUIntegerMax;  //denotes an object that cannot be released
29 }
30  
31 - (void)release
32 {
33     //do nothing
34 }
35  
36 - (id)autorelease
37 {
38     return self;
39 }

If you want a singleton instance (created and controlled by the class factory method) but also have the ability to create other instances as needed through allocation and initialization, do not overrideallocWithZone: and the other methods following it as shown in Listing 2-15.


【原】ios下比较完美的单例模式,已验证

 

网上关于ios单例模式实现的帖子已经很多了,有很多版本,里面有对的也有不对的。我在使用过程中很难找到一个比较完美的方法,索性自己写一个吧,经过项目验证是比较合理的一个版本。

复制代码
static PRAutoLoginView *s_sharedInstance = nil;
+ (PRAutoLoginView *)shareInstance
{
    @synchronized(self)
    {
        if (s_sharedInstance == nil) {
            s_sharedInstance = [[[self class] hideAlloc] init];
        }
    }
    return s_sharedInstance;
}

#pragma mark --
#pragma mark singleton apis
+ (id)hideAlloc
{
    return [super alloc];
}

+ (id)alloc//彻底屏蔽掉alloc函数
{
    NSAssert(1 == 0, @"[PRAutoLoginView]please use +shareInstance instead of alloc!");
    return nil;
}

+ (id)new
{
    return [self alloc];
}

+ (id)allocWithZone:(struct _NSZone *)zone
{
    @synchronized(self)
    {
        if (s_sharedInstance == nil) {
            s_sharedInstance = [super allocWithZone:zone];
            return s_sharedInstance;
        }
    }
    return nil;
}

- (id)copyWithZone:(NSZone *)zone
{
    NSAssert(1 == 0, @"[PRAutoLoginView]copy is not permitted!");
    [self retain];
    return self;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
    return [self copyWithZone:zone];
}
复制代码

这里要注意的一点时,allocWithZone时默认调用的,即使你没有显式地调用alloc或者allocWithZone,因此需要重载

原文地址:https://www.cnblogs.com/ioriwellings/p/2881066.html