1.
Code:
@interface SAMNetworkingTool : NSObject
+ (instancetype)shareNetworkingTool;
@end
@implementation SAMNetworkingTool
static id instance;
// 因为历史遗留问题,每次调用alloc的时候都会先调用allocWithZone
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 这个函数在该程序中只执行一次
instance = [super allocWithZone:zone];
});
return instance;
}
+ (id)copyWithZone:(struct _NSZone *)zone{
return instance;
}
+ (instancetype)shareNetworkingTool{
return [[self alloc] init];
}
@end
Test:
- (void)viewDidLoad {
[super viewDidLoad];
for (int i = 0; i< 10; i++) {
SAMNetworkingTool *tool = [SAMNetworkingTool shareNetworkingTool];
NSLog(@"%@",tool);
}
[self performSelectorInBackground:@selector(testDemo) withObject:nil];
}
- (void)testDemo {
puts("-----");
for (int i = 0; i< 10; i++) {
SAMNetworkingTool *tool = [SAMNetworkingTool shareNetworkingTool];
NSLog(@"%@",tool);
}
}
单例实现:(两种方式:互斥锁(@synchronized(self))和一次性代码(dispatch_once));
2.1互斥锁 @synchronized(self):
<1>.在 .m 文件中保留一个全局的 static 的实例.
static id _instance;
<2>.重写若干方法(allocWithZone:和 copyWithZone:)并提供一个类方法让外界访问唯一的实例.
//(1)重写 allocWithZone:方法,在这里创建唯一的实例(注意线程安全). //alloc 内部都会调用这个方法.
+(instancetype)allocWithZone:(struct _NSZone *)zone {
if (_instance == nil) { // 防止频繁加锁
@synchronized(self) {
if (_instance == nil) { // 防止创建多次
_instance = [super allocWithZone:zone];
}
}
}
return _instance;
}
//(2)重写 copyWithZone:方法.
+(id)copyWithZone:(struct _NSZone *)zone
{
return _instance;
}
//(3)提供1个类方法让外界访问唯一的实例
+(instancetype)shareSingleton
{
if (!_instance) { // 防止频繁加锁
@synchronized(self){
if (!_instance) { // 防止创建多次
_instance = [[self alloc] init];
}
}
}
return _instance;
}
2
一次性代码(dispatch_once):
<1>.在 .m 文件中保留一个全局的 static 的实例.
static id _instance;
<2>.重写若干方法(allocWithZone:和 copyWithZone:)并提供一个类方法让外界访问唯一的实例.
//(1)重写 allocWithZone:方法,在这里创建唯一的实例(注意线程安全).
+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [super allocWithZone:zone];
});
return _instace;
}
//(2)重写 copyWithZone:方法.
+(id)copyWithZone:(struct _NSZone *)zone
{
return _instance;
}
//(3)提供1个类方法让外界访问唯一的实例
+ (instancetype)shareSingleton
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instace = [[self alloc] init];
});
return _instace;
}
注意:在 ARC 和 MRC 中单例的实现方式略有不同. MRC 下单例的实现比 ARC 多了几个内存管理的方法:
MRC 中增加如下方法的实现:
- (instancetype)retain { return self; }
- (NSUInteger)retainCount { return 1; }
- (oneway void)release {}
- (instancetype)autorelease { return self; }
3.判断当前环境(ARC/MRC)
#if __has_feature(objc_arc)
// ARC
#else
// MRC
#endif
注意:,单例最好只提供一个创建单例的方式
如 创建一个访问网络的管理类
#import "AFHTTPSessionManager.h"
@interface SAMNetworkingTool : AFHTTPSessionManager
+ (instancetype)shareNetWorkingManager;
@end
#import "SAMNetworkingTool.h"
@implementation SAMNetworkingTool
static id _instance;
+ (instancetype)shareNetWorkingManager{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *sett = [NSURLSessionConfiguration defaultSessionConfiguration];
sett.timeoutIntervalForRequest = 15;
NSURL *baseUrl = [NSURL URLWithString:@"http://c.m.163.com/nc/"];
_instance = [[SAMNetworkingTool alloc] initWithBaseURL:baseUrl sessionConfiguration:sett];
});
return _instance;
}
对外只提供一种方式创建该对象,,