IOS设计模式——单例模式

单例模式是23种设计模式中较容易实现的设计模式之一,目的是为了在程序运行时只产生一个对象,应用场景主要是1、类只能有一个实例,而且必须从一个为人熟知的访问点对其访问。2、这个唯一的实例只能通过子类化进行扩展,而且扩展的对象不会破坏客户端代码。3、主要应用于工具类和调用次数比较多的类。我们这里只介绍在ARC模式下的单例模式,下面给出两种最典型的OC语言单例模式的代码:

一、不使用GCD的单例模式

头文件

 1 //
 2 //  DataTool.h
 3 //  02-单例模式
 4 //
 5 //  Created by zhangjing on 15/7/5.
 6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 
11 @interface DataTool : NSObject
12 + (instancetype)sharedDataTool;
13 @end

实现文件

 1 //
 2 //  DataTool.m
 3 //  02-单例模式
 4 //
 5 //  Created by zhangjing on 15/7/5.
 6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
 7 //
 8 
 9 #import "DataTool.h"
10 
11 @implementation DataTool
12 static id _instance;
13 
14 /**
15  *  alloc方法内部会调用这个方法
16  */
17 + (id)allocWithZone:(struct _NSZone *)zone
18 {
19     if (_instance == nil) { // 防止频繁加锁
20         @synchronized(self) {
21             if (_instance == nil) { // 防止创建多次
22                 _instance = [super allocWithZone:zone];
23             }
24         }
25     }
26     return _instance;
27 }
28 
29 + (instancetype)sharedDataTool
30 {
31     if (_instance == nil) { // 防止频繁加锁
32         @synchronized(self) {
33             if (_instance == nil) { // 防止创建多次
34                 _instance = [[self alloc] init];
35             }
36         }
37     }
38     return _instance;
39 }
40 
41 - (id)copyWithZone:(NSZone *)zone
42 {
43     return _instance;
44 }
45 @end

二、使用GCD的单例模式

引入GCD后我们将不再担心多线程的问题,也不用在代码中显式的为生成对象代码段上锁

头文件

 1 //
 2 //  GCDDataTool.h
 3 //  02-单例模式
 4 //
 5 //  Created by zhangjing on 15/7/5.
 6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 
11 @interface GCDDataTool : NSObject
12 + (instancetype)sharedGCDDataTool;
13 @end

实现文件

 1 //
 2 //  GCDDataTool.m
 3 //  02-单例模式
 4 //
 5 //  Created by zhangjing on 15/7/5.
 6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
 7 //
 8 
 9 #import "GCDDataTool.h"
10 
11 @implementation GCDDataTool
12 static id _instace;
13 
14 + (id)allocWithZone:(struct _NSZone *)zone
15 {
16     static dispatch_once_t onceToken;
17     dispatch_once(&onceToken, ^{
18         _instace = [super allocWithZone:zone];
19     });
20     return _instace;
21 }
22 
23 + (instancetype)sharedGCDDataTool
24 {
25     static dispatch_once_t onceToken;
26     dispatch_once(&onceToken, ^{
27         _instace = [[self alloc] init];
28     });
29     return _instace;
30 }
31 
32 - (id)copyWithZone:(NSZone *)zone
33 {
34     return _instace;
35 }
36 
37 @end

 

 

以上是单例模式最常见的实现的两种方式,因为代码比较成型,所以我们可以简化一下。

 1 // .h文件
 2 #define SingletonH(name) + (instancetype)shared##name;
 3 
 4 // .m文件
 5 #if __has_feature(objc_arc)
 6 
 7 #define SingletonM(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 SingletonM(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 //
 2 //  SDataTool.h
 3 //  02-单例模式
 4 //
 5 //  Created by zhangjing on 15/7/5.
 6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 #import "Singleton.h"
11 
12 @interface SDataTool : NSObject
13 SingletonH(SDataTool);
14 
15 @end

实现文件

 1 //
 2 //  SDataTool.m
 3 //  02-单例模式
 4 //
 5 //  Created by zhangjing on 15/7/5.
 6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
 7 //
 8 
 9 #import "SDataTool.h"
10 
11 @implementation SDataTool
12 SingletonM(SDataTool);
13 
14 @end

注:我们也可以把引用写在.pch文件中

例如

 1 //
 2 //  PrefixHeader.pch
 3 //  03——单例模式IOS
 4 //
 5 //  Created by zhangjing on 15/7/5.
 6 //  Copyright (c) 2015年 zhangjing. All rights reserved.
 7 //
 8 
 9 
10 #ifdef __OBJC__//如果是OC语言文件
11 #import "Singleton.h"
12 #endif

这样在其他OC语言文件中就不用特意引用了

posted @ 2015-07-05 21:24  zhangjing022  阅读(152)  评论(0编辑  收藏  举报