Objective-c 单例设计模式(Singleton)

单例是一种重要的概念,它是一种极其便利的设计模式。在iPhone SDK中大量使用了单例的概念,例如,UIApplication的sharedApplication方法,任何时候都会返回一个当前应用程序的UIApplication实例。

有时候我们在一个程序几乎所有的地方都要使用某一数据并且要对其进行操作并且这个数据是单一的,全局只需要一个,这种情况下我们也许就会使用单例了

虽然单例很好用,但是不要滥用,因为单例会再程序运行过程中一直存在,不会被销毁(相当于直接在内存上扒了一块下来)

之前公司的航空项目中,用户订票时用的日期,等相关信息最好使用单例,电商APP中的购物车应该也是用的单例

下面就说说怎么创建一个单例===========因为现在有很多老项目是MRC的,也会用到单例随意这里也会给出MRC下单例的创建方法

1、为单例对象实现一个静态实例,并初始化,然后设置成nil,

2、实现一个实例构造方法检查上面声明的静态实例是否为nil,如果是则新建并返回一个本类的实例,

3、重写allocWithZone方法,用来保证其他人直接使用alloc和init试图获得一个新实力的时候不产生一个新实例,

4、适当实现allocWitheZone,copyWithZone,release和autorelease(ARC下不需要事先release等MRC下特有的方法)

单当我们项目中有多个需要实现的单例类时,出了类名不一样其他的基本都一样,所以我们最好将单例抽取成一个宏

下面就是这个宏

// .h文件的实现
#define SingletonH(methodName) + (instancetype)shared##methodName;

// .m文件的实现
#if __has_feature(objc_arc) // 是ARC
#define SingletonM(methodName) 
static id _instace = nil; 
+ (id)allocWithZone:(struct _NSZone *)zone 
{ 
if (_instace == nil) { 
static dispatch_once_t onceToken; 
dispatch_once(&onceToken, ^{ 
_instace = [super allocWithZone:zone]; 
}); 
} 
return _instace; 
} 

- (id)init 
{ 
static dispatch_once_t onceToken; 
dispatch_once(&onceToken, ^{ 
_instace = [super init]; 
}); 
return _instace; 
} 

+ (instancetype)shared##methodName 
{ 
return [[self alloc] init]; 
} 
+ (id)copyWithZone:(struct _NSZone *)zone 
{ 
return _instace; 
} 

+ (id)mutableCopyWithZone:(struct _NSZone *)zone 
{ 
return _instace; 
}

#else // 不是ARC

#define SingletonM(methodName) 
static id _instace = nil; 
+ (id)allocWithZone:(struct _NSZone *)zone 
{ 
if (_instace == nil) { 
static dispatch_once_t onceToken; 
dispatch_once(&onceToken, ^{ 
_instace = [super allocWithZone:zone]; 
}); 
} 
return _instace; 
} 

- (id)init 
{ 
static dispatch_once_t onceToken; 
dispatch_once(&onceToken, ^{ 
_instace = [super init]; 
}); 
return _instace; 
} 

+ (instancetype)shared##methodName 
{ 
return [[self alloc] init]; 
} 

- (oneway void)release 
{ 

} 

- (id)retain 
{ 
return self; 
} 

- (NSUInteger)retainCount 
{ 
return 1; 
} 
+ (id)copyWithZone:(struct _NSZone *)zone 
{ 
    return _instace; 
} 
 
+ (id)mutableCopyWithZone:(struct _NSZone *)zone 
{ 
    return _instace; 
}

#endif

里面用has_feature来判断有没有使用ARC,这样引入这个宏的时候你就不用担心是ARC还是非ARC了

只需要在实现单例的.h文件写上

SingletonH(methodName)

在.m文件里面写上

SingletonM(methodName)

原文地址:https://www.cnblogs.com/xyzaijing/p/3855649.html