【单例模式】单例模式 & GCD单例模式 & 将封装单例模式到宏

懒汉式单例模式

下面的代码块, 基本是单例模式的完整版本了.

可扩展的地方,可以在init方法中作扩展.

 1 // static 在全局变量的作用域仅限于当前文件内部
 2 static id _instance;
 3 
 4 /**
 5  *  alloc方法内部会调用这个方法 , zone是代表内存块的意思
 6  */
 7 + (id)allocWithZone:(struct _NSZone *)zone
 8 {
 9     // 首先判断防止频繁加锁 , 如果不判断,每次进来先加锁在判断
10     if (_instance == nil) {
11         // 只有第一次为空得时候才进来, 然后加锁. 必须加锁, 防止多线程同时操作同一变量
12         @synchronized(self) {
13             // 某条线程进来之后, 首先判断变量是否为空,如果为空,才执行下面语句
14             if (_instance == nil) {
15                 // 内部默认做法,调用父类方法分配内存空间
16                 _instance = [super allocWithZone:zone];
17             }
18         }
19     }
20     
21     // 直接返回对象
22     return _instance;
23 }
24 
25 /**
26  *  单例模式应该实现一个方法,让别人调用创建,并且创建无数次都应该是同一个对象
27  *
28  */
29 + (instancetype)sharedTool
30 {
31     if (_instance == nil) { // 防止频繁加锁
32         @synchronized(self) {
33             if (_instance == nil) { // 防止创建多次
34                 // alloc 又会调用上面的allocWithZone方法
35                 _instance = [[self alloc] init];
36             }
37         }
38     }
39     return _instance;
40 }
41 
42 // 应该提供该方法, 防止以后别人需要用copy得时候,也保证创建出来的对象是同一对象
43 - (id)copyWithZone:(NSZone *)zone
44 {
45     return _instance;
46 }

 

 

GCD 单例模式

// 用来保存唯一的单例对象, 同样也要加上static,防止别人能修改该字段
static id _instace;

/**
 *
 */
+ (id)allocWithZone:(struct _NSZone *)zone
{
    /**
     *  dispatch_once只会执行一次,而且内部自动封装了锁,更简便安全
     */
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [super allocWithZone:zone];
    });
    return _instace;
}

+ (instancetype)sharedDataTool
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instace = [[self alloc] init];
    });
    return _instace;
}



/**
 *  防止Copy创建对象
 */
- (id)copyWithZone:(NSZone *)zone
{
    return _instace;
}

 

宏实现单例 

新建一个.h文件,将下列代码复制进去.即可生成一个单例模式文件

 1 // .h文件
 2 #define HMSingletonH(name) + (instancetype)shared##name;
 3 
 4 // .m文件
 5 #if __has_feature(objc_arc)
 6 
 7     #define HMSingletonM(name) \
 8     static id _instace; \
 9  \
10     + (id)allocWithZone:(struct _NSZone *)zone \
11     { \
12         static dispatch_once_t onceToken; \
13         dispatch_once(&onceToken, ^{ \
14             _instace = [super allocWithZone:zone]; \
15         }); \
16         return _instace; \
17     } \
18  \
19     + (instancetype)shared##name \
20     { \
21         static dispatch_once_t onceToken; \
22         dispatch_once(&onceToken, ^{ \
23             _instace = [[self alloc] init]; \
24         }); \
25         return _instace; \
26     } \
27  \
28     - (id)copyWithZone:(NSZone *)zone \
29     { \
30         return _instace; \
31     }
32 
33 #else
34 
35     #define HMSingletonM(name) \
36     static id _instace; \
37  \
38     + (id)allocWithZone:(struct _NSZone *)zone \
39     { \
40         static dispatch_once_t onceToken; \
41         dispatch_once(&onceToken, ^{ \
42             _instace = [super allocWithZone:zone]; \
43         }); \
44         return _instace; \
45     } \
46  \
47     + (instancetype)shared##name \
48     { \
49         static dispatch_once_t onceToken; \
50         dispatch_once(&onceToken, ^{ \
51             _instace = [[self alloc] init]; \
52         }); \
53         return _instace; \
54     } \
55  \
56     - (id)copyWithZone:(NSZone *)zone \
57     { \
58         return _instace; \
59     } \
60  \
61     - (oneway void)release { } \
62     - (id)retain { return self; } \
63     - (NSUInteger)retainCount { return 1;} \
64     - (id)autorelease { return self;}
65 
66 #endif

 

以上三种都是可运用的单例模式

单例模式是什么?

 -> 单例模式是确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类

 

单例模式的作用?

 -> 可以保证在程序运行过程, 一个类只有一个实例,而且该实例易于供外界访问,从而方便地控制了实例的个数,并节约系统资源

 

单例模式的使用场合?

 -> 整个应用程序中, 共享一份资源,或者这份资源只需要创建初始化1次.

     例如 : 一些工具类,(使用到项目各个地方,并且一般只有一份.)

            : 例如一个注册的页面, 点击注册跳到注册页面.但是如果这个时候,再点击注册,我们希望一般都是进到同一个注册的页面,所以,这里应该就使用单例模式.

 

posted @ 2015-10-23 19:50  Travin-C  阅读(220)  评论(0编辑  收藏  举报