能够保证的程序运行过程,一个类只有一个示例,并且该实例易于供外界访问设计模式
从而方便地控制了实例个数,并节约系统资源。安全
类只能有一个实例,而且必须从一个为人数值的访问点对其访问。框架
这个惟一的实例只能经过子类化进行拓展,而且拓展的对象不会破坏客户端代码。学习
能够用宏判断是否为ARC环境spa
#if _has_feature(objc_arc)#else//MRC#endif
ARC中单例模式的实现.net
在 .m中保留一个全局的static的实例线程
static id _instance; //重写allocWithZone:方法,在这里建立惟一的实例(注意线程安全) + (instancetype)allocWithZone:(struct _NSZone *)zone { @synchronized(self) { if (_instance == nil) { _instance = [super allocWithZone:zone]; } } return _instance; }
提供1个类方法让外界访问惟一的实例设计
+ (instancetype)sharedInstanceTool{ @synchronized(self){ if(_instance == nil){ _instance = [[self alloc] init]; } } return _instance; }
实现copyWithZone:方法指针
-(id)copyWithZone:(struct _NSZone *)zone{ return _instance; }
sharedInstanceTool
,首先检查类的惟一实例是否已经建立,若是就会建立实例并将其返回。而之因此调用super而不是self,是由于已经在self中重载了基本的对象分配的方法,须要借用父类的功能来帮助处理底层内存的分配。allocWithZone:(struct _NSZone*)zone
方法中,只是返回从sharedInstanceTool
方法返回的类实例。而一样的在Cocoa框架中调用allocWithZone:(struct _NSZone*)zone
会分配内存,引用计数会设置为1,而后返回实例。一样的重写(id)copyWithZone:(struct _NSZone *)zone
方法,也是为了保证不会返回实例的副本,而是返回self.返回同一个实例。+(instancetype)sharedInstance { static WMSingleton *singleton = nil; if (! singleton) { singleton = [[self alloc] initPrivate]; } return singleton; } - (instancetype)init { @throw [NSException exceptionWithName:@"这个是个单例" reason:@"应该这样调用 [WMSingleton sharedInstance]" userInfo:nil]; return nil; }//实现本身真正的私有初始化方法- (instancetype)initPrivate { self = [super init]; return self; }
@synchronized
来添加了一个互斥锁,以此来保证线程安全。而如今咱们开始尝试用线程的方式来实现一个加单的单例。static WMObject *_instance; + (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [super allocWithZone:zone]; }); return _instance; } + (instancetype)sharedInstance { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } - (id)copyWithZone:(NSZone *)zone { return _instance; }
sharedInstanceTool
,首先检查类的惟一实例是否已经建立,若是就会建立实例并将其返回。而略有不一样的地方就是咱们此次经过dispatch_once_t
来保证线程的安全性。至于dispatch_once_t
的用法这里就一一赘述了,线程的相关教程都会有其相关的描述。WMSingleton.h
// .h文件#define WMSingletonH(name) + (instancetype)shared##name; // .m文件#define WMSingletonM(name) static id _instance; + (instancetype)allocWithZone:(struct _NSZone *)zone { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [super allocWithZone:zone]; }); return _instance; } + (instancetype)shared##name { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _instance = [[self alloc] init]; }); return _instance; } - (id)copyWithZone:(NSZone *)zone { return _instance; }
//.h类//引入这个宏文件#import "WMSingleton.h"@interface WMObject : NSObjectWMSingletonH(object)@end//.m类@implementation WMObjectWMSingletonM(Car)@end
Cocoa Touch
框架中一样存在着大量的单例模式让咱们来学习,好比UIApplication
、UIAccelerometer
、以及NSFileManager
等等。因此在单例模式的学习上仍是依旧的任重道远呀。。。