#if _has_feature(objc_arc)#else//MRC#endif
static id _instance; //重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全) + (instancetype)allocWithZone:(struct _NSZone *)zone{ @synchronized(self) { if (_instance == nil) { _instance = [super allocWithZone:zone]; } } return _instance;}
+ (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
等等。所以在单例模式的学习上还是依旧的任重道远呀。。。联系客服