iOS设计模式单例模式 iOS

(一)什么是单例模式(Singleton)

单例模式:保证一个类仅有一个实例,并提供一个访问它的全局访问点 *最初的定义是在<设计模式>(Addison-Wesley)中

解读

1>在数学与逻辑学中,Singleton的定义是:"有且只有一个元素的集合".

2>在程序中,无论以什么方式创建对象,总是放回第一次创建的对象

(二)何时使用单例模式

类只能有一个实例,并且必须从一个为人熟知的访问点对其进行访问,比如工厂方法

避免重复生成同一对象浪费内存空间

(三)实现单例模式的思想-拦截创建对象的方法,在调用创建对象的方法时,总是返回第一次创建的对象

(四)在iOS中实现单例模式的方法

1>通过GCD中的once函数来进行实现

1 #import <Foundation/Foundation.h>
2 
3 @interface ZDZPerson : NSObject
4 
5 + (instancetype)sharedPerson;
6 @end
ZDZPerson.h
 1 #import "ZDZPerson.h"
 2 
 3 @interface ZDZPerson () <NSCopying>
 4 
 5 @end
 6 
 7 @implementation ZDZPerson
 8 
 9 //创建一个全局变量(目的是在整个生命周期都可以访问到)
10 static id _person;
11 
12 //调用alloc方法或其他生成对象的方法时会默认调用allocWithZone方法
13 + (instancetype)allocWithZone:(struct _NSZone *)zone {
14     static dispatch_once_t tokenOnce;
15     dispatch_once(&tokenOnce, ^{
16         _person = [super allocWithZone:zone];
17     });
18     return _person;
19 }
20 
21 //实现此方法避免因copy对象时 产生新的对象
22 - (id)copyWithZone:(NSZone *)zone {
23     return _person;
24 }
25 
26 //自定义sharedPerson方法 返回对象
27 + (instancetype)sharedPerson {
28     static dispatch_once_t tokenOnce;
29     dispatch_once(&tokenOnce, ^{
30         _person = [[self alloc] init];
31     });
32     return _person;
33 }
34 
35 @end
ZDZPerson.m

2>通过为线程加锁的方式实现

1 #import <Foundation/Foundation.h>
2 
3 @interface ZDZAnimal : NSObject
4 + (instancetype)sharedAnimal;
5 @end
ZDZAnimal.h
 1 #import "ZDZAnimal.h"
 2 
 3 @implementation ZDZAnimal
 4 static id _animal;
 5 
 6 //调用alloc方法或其他生成对象的方法时会默认调用allocWithZone方法
 7 + (instancetype)allocWithZone:(struct _NSZone *)zone {
 8     @synchronized(self) {
 9         if (_animal == nil) {
10             _animal = [super allocWithZone:zone];
11         }
12     }
13     return _animal;
14 }
15 
16 //实现此方法避免因copy对象时 产生新的对象
17 - (id)copyWithZone:(NSZone *)zone {
18     return _animal;
19 }
20 
21 //自定义sharedPerson方法 返回对象
22 + (instancetype)sharedAnimal {
23     @synchronized(self) {
24         _animal = [[self alloc] init];
25     }
26     return _animal;
27 }
28 @end
ZDZAnimal.m

(五)实现单例类代码的复用:通过#define来实现单例代码的复用

1>代码解读

#define kZDZSingletonH(name) + (instancetype)shared##name;  可以通过此方式动态设置函数名

扩展:

#define Conn(x,y) x##y
#define ToChar(x) #@x
#define ToString(x) #x

x##y表示什么?表示x连接y,举例说:
int n = Conn(123,456);   结果就是n=123456;
char* str = Conn("asdf", "adf")结果就是 str = "asdfadf";
怎么样,很神奇吧

再来看#@x,其实就是给x加上单引号,结果返回是一个const char。举例说:
char a = ToChar(1);结果就是a='1';
做个越界试验char a = ToChar(123);结果是a='3';
但是如果你的参数超过四个字符,编译器就给给你报错了!error C2015: too many characters in constant   :P

最后看看#x,估计你也明白了,他是给x加双引号
char* str = ToString(123132);就成了str="123132";

注:转载他人

1>工具类代码

 1 #define kZDZSingletonH(name) + (instancetype)shared##name;
 2 
 3 #define kZDZSingletonM(name)\
 4 static id _instance;\
 5 \
 6 + (instancetype)allocWithZone:(struct _NSZone *)zone {\
 7     static dispatch_once_t tokenOnce;\
 8     dispatch_once(&tokenOnce, ^{\
 9         _instance = [super allocWithZone:zone];\
10     });\
11     return _instance;\
12 }\
13 \
14 - (id)copyWithZone:(NSZone *)zone {\
15     return _instance;\
16 }\
17 \
18 + (instancetype)shared##name {\
19     static dispatch_once_t tokenOnce;\
20     dispatch_once(&tokenOnce, ^{\
21         _instance = [[self alloc] init];\
22     });\
23     return _instance;\
24 }
ZDZSingleton.h

2>使用方法

1 #import <Foundation/Foundation.h>
2 #import "ZDZSingleton.h"
3 
4 @interface ZDZComputer : NSObject
5 
6 kZDZSingletonH(Computer)
7 
8 @end
ZDZComputer.h
1 #import "ZDZComputer.h"
2 
3 @implementation ZDZComputer
4 
5 kZDZSingletonM(Computer)
6 
7 @end
ZDZComputer.m
原文地址:https://www.cnblogs.com/denz/p/5248217.html