【非凡程序员】单例模式

单例(单态)模式
单例设计模式确保对于一个给定的类只有一个实例存在,这个实例有一个全局唯一的访问点。它通常采用懒加载的方式在第一次用到实例的时候再去创

建它。
注意 :苹果大量使用了此模式。例如: [NSUserDefaults standardUserDefaults] , [UIApplication sharedApplication] ,  [UIScreen mainScreen] , 

[NSFileManager defaultManager] ,所有的这些方法都返回一个单例对象。
你很可能会想为什么这么关心是否一个类有多个实例?毕竟代码和内存都是廉价的,对吗? 
有一些情况下,只有一个实例显得非常合理。举例来说,你不需要有多个 Logger 的实例,除非你想去写多个日志文件。或者一个全局的配置处理类:

实现线程安全的方式访问共享实例是容易的,比如一个配置文件,有好多个类同时修改这个文件。


对于单例模式有一些需要需要注意的点:
1. 声明一个静态变量去保存类的实例,确保它在类中的全局可用性。
2. 声明一个静态变量 dispatch_once_t , 它确保初始化器代码只执行一次
3. 使用 Grand Central Dispatch(GCD) 执行初始化 LibraryAPI 变量的 block. 这    正是单例模式的关键:一旦类已经被初始化,初始化器永远不会再

被调用。
下一次你调用 sharedInstance 的时候, dispatch_once 块中的代码将不会执行(因为它已经被执行了一次),你将得到原先已经初始化好的实例。 

在iOS中,单例有两种实现方式(至少我目前只发现两种)。根据线程安全的实现来区分,一种是使用@synchronized ,另一种是使用GCD的

dispatch_once函数。

要实现单例,首先需要一个static的指向类本身的对象,其次需要一个初始化类函数。下面是两种实现的代码。

1、@synchronized

static InstanceClass *instance;+ (InstanceClass *)defaultInstance{
    @synchronized (self){
        if (instance == nil) {
            instance = [[InstanceClass alloc] init];
        }
    }
   
    return instance;}
2、GCD

static InstanceClass *instance;
+ (InstanceClass *)defaultInstance{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
                  instance = [[InstanceClass alloc] init];
    });
   
    return instance;}
总的来说,两种实现效果相同,我们今天只学习力前者。

 

 

单例模式是一种常用的软件设计模式,在应用这个模式时,单例对象的类必须保证只有一个实例存在。通过单例模式可以保证系统中一个类只有一个

实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方

案。

    iOS中最常见的单例就是UIApplication,UIWindow.

单例的实现步骤:

    1> 重写allocWithZone方法;

    allocWithZone方法是对象分配内存空间时,最终会调用的方法,重写该方法,保证只会分配一个内存空间。

    2> 建立sharedXXX类方法,便于其他类访问;

方法实现代码如下:


#import <Foundation/Foundation.h>
 
@interface Ticket : NSObject
 
+(id)sharedTiket
 
@end
 
#import "JNInstance.h"
 
@implementation JNInstance
 
+(id)allocWithZone:(struct _NSZone *)zone
{
    static Ticket *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super allocWithZone:zone];
        });
        return instance;
}
 
+(id)sharedTiket
{
    return [self allocWithZone:nil];
}
    dispatch_once 是线程安全的,能够做到在多线程的环境下Block中的代码只会被执行一次;

单例模式

优点:

    可以阻止其他对象实例化单例对象的副本,从而确保所有对象都访问唯一实例;

缺点:

    单例对象一旦建立,对象指针是保存在静态区的,单例对象在堆中分配的内存空间,会在应用程序终止后才会被释放;

提示:

    只有确实需要唯一使用的对象才需要考虑单例模式,不要滥用单例。

相关内容详细介绍博客:

http://my.oschina.net/Mrsyi/blog/208197

http://my.oschina.net/u/574245/blog/203440

http://my.oschina.net/sunqichao/blog/161964

 

 

你可能感兴趣的:(非凡程序员)