首页 > 代码库 > 如何写一个比较严谨的单例Singleton模式

如何写一个比较严谨的单例Singleton模式

iOS真正意义上的单例模式:

我们在程序中很多时候要保证一个类只有一个唯一的实例,一般情况下初始化对象是通过[[Class alloc]init]来完成的,alloc是分配内存空间,init是对象的初始化,分配对象内存空间的另一个方法是allocWithZone方法,实际操作中当调用alloc方法来给对象分配空间时,默认也调用了allocWithZone方法。如果我们在初始化对象的时候没有使用alloc方法,而是直接使用allocWithZone方法的话,就没法保证这个单例是真正意义上的单例了,所以要实现一个真正意义上的单例至少要重写allocWithZone这个方法。但是在默写特殊情况下copyWithZone,mutableCopyWithZone,copy,mutableCopy,init也会创建一个新的实例,所以为了避免所以引起alloc的的情况,我们也最好实现以上方法的重写。这样就可以保证单例的唯一性了。具体实现如下:

1.首先在头文件中声明单例方法:

/**

 * gets singleton object.

 * @return singleton

 */

+ (MySingleton*)sharedInstance;

2.在.m文件中实现以下方法

static MySingleton *SINGLETON = nil;//声明一个静态的单例对象

static bool isFirstAccess = YES;//更为严谨的标识单例地址是唯一的 主要用于标识初始化对象时的重复

#pragma mark  Public Method - 控制了单例的创建和访问

+ (id)sharedInstance 

{

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{//通过GCD来保证SINGLETON在程序运行期间内存只会被分配一次

        isFirstAccess = NO;

        SINGLETON = [[super allocWithZone:NULL] init];    

    });

    return SINGLETON;

}

 #pragma mark - Life Cycle 通过重写其声明周期方法来进一步严谨保证单例地址的唯一性

 + (id) allocWithZone:(NSZone *)zone

{

    return [self sharedInstance];

}

 + (id)copyWithZone:(struct _NSZone *)zone

{

    return [self sharedInstance];

}

 + (id)mutableCopyWithZone:(struct _NSZone *)zone

{

    return [self sharedInstance];

}

- (id)copy

{

    return [[MySingleton alloc] init];

}

 - (id)mutableCopy

{

    return [[MySingleton alloc] init];

}

 - (id) init

{

    if(SINGLETON){

        return SINGLETON;

    }

    if (isFirstAccess) {

        [self doesNotRecognizeSelector:_cmd];

    }

    self = [super init];

    return self;

}

如何写一个比较严谨的单例Singleton模式