美文网首页设计模式
单例模式(二)

单例模式(二)

作者: ef463f819996 | 来源:发表于2016-05-02 18:00 被阅读40次

1、在上一篇单例模式(一)中介绍过如何创建单例,那么接下来如何简化一下单例模式。之前的单例模式是这样的:

SpiderMan.h


#import@interface SpiderMan : NSObject

+ (instancetype)shanreSpiderMan;

@end

SpiderMan.m


#import "SpiderMan.h"

@implementation SpiderMan

static id _instance;

+ (id)allocWithZone:(struct _NSZone *)zone

{

if (_instance == nil) { // 防止频繁加锁

@synchronized(self) {

if (_instance == nil) { // 防止创建多次

_instance = [super allocWithZone:zone];

}

}

}

return _instance;

}

+ (id)shanreSpiderMan

{

if (_instance == nil) { // 防止频繁加锁

@synchronized(self) {

if (_instance == nil) { // 防止创建多次

_instance = [[self alloc] init];

}

}

}

return _instance;

}

- (id)copyWithZone:(NSZone *)zone

{

return _instance;

}

@end

可以发现,要经常写这一东西:


if (_instance == nil) { // 防止频繁加锁

@synchronized(self) {

if (_instance == nil) { // 防止创建多次

_instance = [[self alloc] init];

}

}

}

这些代码其实可以用另外一种方式来实现,GCD中有一个方法是只执行一次的,即:

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{ });

使用该方法来代替以上代码可以简化许多:


+ (id)allocWithZone:(struct _NSZone *)zone

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instance = [super allocWithZone:zone];

});

return _instance;

}

详细代码也可以看github上的例子里的People类。

2、以上的单例都是在ARC环境下的,在非ARC环境下需要再做处理:


- (oneway void)release { }

- (id)retain { return self; }

- (NSUInteger)retainCount { return 1;}

- (id)autorelease { return self;}

  • (oneway void)release {} :为了防止对象被释放;

  • (id) retain {return self }: 为了防止产生新的对象;

  • (NSUInteger)retainCount {return 1;} :保证一个对象引用计数始终为1;

3、如果一个项目当中有非常多的单例类,对每个单例类都进行


+ (id)allocWithZone:(struct _NSZone *)zone

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instance = [super allocWithZone:zone];

});

return _instance;

}

+ (id)sharePeoper

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instance = [[self alloc]init];

});

return _instance;

}

- (id)copyWithZone:(NSZone *)zone

{

return _instance;

}

这样子会非常繁琐,其实可以做相应地简化,简化的方法是:创建一个头文件,宏定义单例头文件和.m文件。如:


// .h文件

#define HMSingletonH + (instancetype)sharedInstance;

// .m文件

#define HMSingletonM \

static id _instance; \

\

+ (id)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; \

}

4、那么接下来需要解决的一个问题就是在ARC环境和MRC环境下如何使用宏定义来适配单例模式。方法还是比较简单的,因为可以使用


#if __has_feature(objc_arc) // arc环境

#else  // mrc 环境

#endif

来判断是在ARC还是在MRC环境下。不多说,直接上代码(在新建的一个头文件里):


// .h文件

#define HMSingletonH(name) + (instancetype)shared##name;

// .m文件

#if __has_feature(objc_arc)

#define HMSingletonM(name) \

static id _instace; \

\

+ (id)allocWithZone:(struct _NSZone *)zone \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [super allocWithZone:zone]; \

}); \

return _instace; \

} \

\

+ (instancetype)shared##name \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [[self alloc] init]; \

}); \

return _instace; \

} \

\

- (id)copyWithZone:(NSZone *)zone \

{ \

return _instace; \

}

#else

#define HMSingletonM(name) \

static id _instace; \

\

+ (id)allocWithZone:(struct _NSZone *)zone \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [super allocWithZone:zone]; \

}); \

return _instace; \

} \

\

+ (instancetype)shared##name \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instace = [[self alloc] init]; \

}); \

return _instace; \

} \

\

- (id)copyWithZone:(NSZone *)zone \

{ \

return _instace; \

} \

\

- (oneway void)release { } \

- (id)retain { return self; } \

- (NSUInteger)retainCount { return 1;} \

- (id)autorelease { return self;}

#endif

以后每次要使用到单例的时候,就导入该头文件,写上两句代码就OK了,例如Person单例:

.h


#import@interface Person : NSObject

ANSingletonH(Person)

@end

.m


#import "Person.h"

@implementation Person

ANSingletonM(Person)

@end

也可以到我的github上查看完整代码

相关文章

  • 单例模式

    一、单例模式介绍 二、单例模式代码实例

  • 单例模式

    一、实现单例模式 或者 二、透明的单例模式 三、用代理实现单例模式 四、JavaScript中的单例模式 在Jav...

  • OC - 单例模式

    导读: 一、什么是单例模式 二、单例的作用 三、常见的单例类 四、自定义单例类的方法 一、什么是单例模式 单例模式...

  • 设计模式-iOS常见

    一、单例模式 系统的单例模式(Singleton Pattern) 二、中介者模式 中介者模式(Mediator ...

  • 【设计模式】单例模式

    单例模式 常用单例模式: 懒汉单例模式: 静态内部类单例模式: Android Application 中使用单例模式:

  • Android设计模式总结

    单例模式:饿汉单例模式://饿汉单例模式 懒汉单例模式: Double CheckLock(DCL)实现单例 Bu...

  • 单例模式

    一、定义 单例模式:单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。 二、单例模式结构...

  • Python 面向对象7: 单例模式

    一、内容 1.1、单例设计模式 1.2、__new__方法 1.3、Python 中的单例 二、单例设计模式 2....

  • 单例模式

    一、介绍 二、单例模式代码实现 三、单例的简介写法

  • Swift单例模式

    1.第一种单例模式 2.第二种单例模式

网友评论

    本文标题:单例模式(二)

    本文链接:https://www.haomeiwen.com/subject/djelrttx.html