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
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
2>通过为线程加锁的方式实现
1 #import <Foundation/Foundation.h> 2 3 @interface ZDZAnimal : NSObject 4 + (instancetype)sharedAnimal; 5 @end
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
(五)实现单例类代码的复用:通过#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 }
2>使用方法
1 #import <Foundation/Foundation.h> 2 #import "ZDZSingleton.h" 3 4 @interface ZDZComputer : NSObject 5 6 kZDZSingletonH(Computer) 7 8 @end
1 #import "ZDZComputer.h" 2 3 @implementation ZDZComputer 4 5 kZDZSingletonM(Computer) 6 7 @end