单例设计模式

来源:互联网 发布:铁线虫入侵知乎 编辑:程序博客网 时间:2024/05/20 05:59

单例模式

原则上,单例是在程序生命周期里只被实例化过一次的 类。为了确保这一点,我们利用类的一个静态方法来生成和访问对象。

因此, 你是通过以便利方法来访问某个类的单例对象的,而不是用 alloc/init或者静态autorelease初始化方法。

在很多时候,我们使用一个某个类的唯一实例。最常见的就是一个程序的主类。

以下是以名为 RootViewController 创建的一个单例函数:

// static 修饰  整个程序运行,只初始化一次

static HMTInputViewController * shareRootViewController = nil;

+(HMTInputViewController *)sharedInstance{

   //  常见创建

   //  需要加一个互斥锁 防止多个线程同时访问

   @synchronized(self){

       if(shareRootViewController == nil){

           shareRootViewController = [[HMTInputViewController allocinit] ;

        }

    }


    //  通过GCD创建

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken,^{


        shareRootViewController = [[HMTInputViewController alloc] init];        

    });


   return shareRootViewController;

}

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


 代码说明:

1. synchronized   这个主要是考虑多线程的程序,这个指令可以将{ } 内的代码限制在一个线程执行,如果某个线程没有执行完,其他的线程如果需要执行就得等着。
2. allocWithZone 这个是重载的,因为这个是从制定的内存区域读取信息创建实例,所以如果需要的单例已经有了,就需要禁止修改当前单例。所以返回 nil


@另一种解释

Singleton 单例模式,又叫单子模式,是一种常见的软件设计模式。这种模式的特点就是应用了 Singleton 单例模式的类必须保证始终只有一个实例(对象)存在。许多时候系统中需要某个类只能同时存在一个对象,而且可以全局调用。

单例模式的思路是一个类能返回对象一个实例(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用 getInstance这个名称);当我们调用这个方法时,如果类持有的实例不为空,就返回这个实例;如果类保持的实例为空,就创建该类的实例,并将实例赋予该类保持的实例,从而限制用户只有通过该类提供的静态方法来得到该类唯一的实例。

单例模式在多线程场合下必须小心使用。当唯一的实例未创建时,如果有两个线程同时调用创建方法,那么他们同时没有检测到唯一的实例存在,从而同时各自创建了一个实例,这样就有两个实例被创建出来,从而违反了单例模式中实例唯一的原则。解决这个问题的办法是为标记类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。

下面用一个例子来说明问题:

一:为你的单例类声明一个静态的实例,并且初始化它的值为nil。

二:在获取实例的方法中(比如下例中的 getInstance),只有在静态实例为nil的时候,产生一个你的类的实例,这个实例通常被称为共享的实例。

三:重写allocWithZone 方法,用于确定:不能够使用其他的方法来创建我们不得实例,限制用户只能通过获取实例的方法得到这个类的实例。所以,我们在allocWithZone方法中直接返回共享的类实例。

四:实现基本的协议方法 copyWithZone、release、retain、retainCount 和 autorelease,用于保证单例具有一个正确的状态。最后四种方法是哟娜与内存管理的代码,并不适用于垃圾收集代码。

0 0