IOS单例模式

软件设计模式大都来源于GoF(四人组)的23种设计模式,在Cocoa和Cocoa Touch框架中的设计模式也基本上是这23种的演变,对于,IOS开发我们首先来看下Cocoa框架下的单例模式。

单例模式就是指在应用中只初始化一次单例类的一个实例,之后就可以在应用中不断被调用。单例模式很重要,作为单例的类一般是做共享资源,例如UIApplication这个类就是一个典型的单例类。我们可以调用其sharedApplication方法获取其实例的方法,例如openURL,可以打开一些内置的IOS应用,像浏览器,google map,打电话,发送email等等。代码如下:

-(void) examples
{
    //打开浏览器示例
    NSURL *url = [NSURL URLWithString:@"https://github.com/"];
    [[UIApplication sharedApplication] openURL:url];
    
    //打电话
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"tel://10086"]];
    
    //发短信
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"sms://10086"]];
}

那我们如何实现单例模式呢?在没引入GCD(Grand Central Dispatch)概念之前,大部分都是遵循四个步骤:

1、为单例对象实现一个静态实例,并初始化,然后设置成nil,

2、实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,

3、重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,

4、适当实现allocWitheZone,copyWithZone,release和autorelease 

代码如下:

static RootViewController *shareRootViewController = nil;
+(RootViewController *)sharedController{
        @synchronized(self){
                if(shareRootViewController == nil){
                        shareRootViewController = [[[self alloc] init] autorelease];
                }
        }
        return shareRootViewController;
}
 
+(id)allocWithZone:(NSZone *)zone{
        @synchronized(self){
                if (shareRootViewController == nil) {
                   shareRootViewController = [super allocWithZone:zone];
                    return  shareRootViewController;
                }
            }
        return nil;
}

代码说明:

1. synchronized   这个主要是考虑多线程的程序,这个指令可以将{ } 内的代码限制在一个线程执行,如果某个线程没有执行完,其他的线程如果需要执行就得等着。

2. allocWithZone  这个是重载的,因为这个是从制定的内存区域读取信息创建实例,所以如果需要的单例已经有了,就需要禁止修改当前单例。所以返回 nil。

3. NSZone  简单来说可以把它想象成一个内存池,alloc或者dealloc这些操作都是在这个内存池中操作的,cocoa总是会分配一个默认的nsZone,任何 默认内存操作都是在这个zone上进行的,使用默认zone存在缺陷,因为他是全局范围的,频繁使用会导致内存的碎片化,尤其是大量的alloc和 dealloc的时候,性能上会受到一定影响。因为你可以自己生成一个zone并将alloc,copy这些限制在这个zone中。

但是当引入GCD后,我们可以利用dispatch_once函数实现单例的控制。

首先在.h声明一个静态变量sharedmanager:

+(Singleton *)sharedmannager
{
    static dispatch_once_t once;
    dispatch_once(&once,^{
        sharedManager = [[self alloc] init];});
    return sharedManager;
}

我们需要做的很简单:

Singleton *single = [Singleton sharedmannager];
优势:

1.线程安全

2.少量代码

3. 和ARC兼容

劣势:

仍然可以创建一个非共享实例:

Singleton *not_single = [[Singleton alloc]init];

总的来说呢,单例模式在数据共享方面很有用,用的也比较多。




你可能感兴趣的:(iOS设计模式)