您的位置:首页 > 其它

单例的完整实现

2016-04-20 12:51 239 查看
1.单例模式的作用

1>可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
2>从而方便地控制了实例个数,并节约系统资源

2.单例模式的使用场合
* 在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)

3.单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码
1>可以用宏判断是否为ARC环境

#if __has_feature(objc_arc)
// ARC
#else
// MRC
#endif

1>ARC环境下单例的两种实现

第一种:懒汉式生成单例

/**

static : 修饰变量

1> 修饰全局变量

* 全局变量的作用域仅限于当前文件内部

2> 修饰局部变量 :

* 局部变量的生命周期
跟 全局变量
类似

* 但是不能改变作用域

* 能保证局部变量永远只初始化1次,在程序运行过程中,永远只有1分内存

*/

在.m中保留一个全局的static的实例

static id _instance;

只允许内部访问。防止外部文件恶意篡改我的数据

如果不添加static 修饰_instance这个全局变量,在外部可以通过extern,在外部修改_instance的值

引用某个全局变量(并非定义)

extern id _instance;

_instance = nil;

extern是在整个项目中查找这个变量

1>在创建单例的是,如果是通过alloc,创建的对象,在底层都会调用

2>重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)

+ (id)allocWithZone:(struct
_NSZone *)zone,所以在创建对象的时候,我们要拦截创建信息

/**

* alloc方法内部会调用这个方法

*/

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

{

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

@synchronized(self) {

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

_instance = [super
allocWithZone:zone];

}

}

}

return
_instance;

}

提供1个类方法让外界访问唯一的实例

+ (instancetype)sharedMusicTool

{

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

@synchronized(self) {

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

_instance = [[self
alloc] init];

}

}

}

return
_instance;

}

// copy 有可能会产生新的对象

// copy方法内部会调用- copyWithZone:

- (id)copyWithZone:(NSZone *)zone

{

return
_instance;

}

方式二:

// 用来保存唯一的单例对象

static id _instace;

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

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instace = [super
allocWithZone:zone];

});

return
_instace;

}

+ (instancetype)sharedDataTool

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instace = [[self
alloc] init];

});

return
_instace;

}

- (id)copyWithZone:(NSZone *)zone

{

return
_instace;

}

饿汉式创建单例的方式:

**

* 当类加载到OC运行时环境中(内存),就会调用一次(一个类只会加载1次)

*/

+ (void)load

{

_instance = [[self
alloc] init];

}

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

{

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

_instance = [super
allocWithZone:zone];

}

return
_instance;

}

+ (instancetype)sharedSoundTool

{

return
_instance;

}

- (id)copyWithZone:(NSZone *)zone

{

return
_instance;

}

///**

// * 当第一次使用这个类的时候才会调用

// */

//+ (void)initialize

//{

// NSLog(@"HMSoundTool---initialize");

//}

非ARC环境下单例的实现:

1>非ARC中(MRC),单例模式的实现(比ARC多了几个步骤)
2>实现内存管理方法
- (id)retain {
return self; }

- (NSUInteger)retainCount {
return 1; }

- (oneway void)release{}

- (id)autorelease {
return self; }

@implementation HMDataTool

// 用来保存唯一的单例对象

static id _instace;

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

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instace = [super
allocWithZone:zone];

});

return
_instace;

}

+ (instancetype)sharedDataTool

{

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;}

简化单例模式:

// .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; \

}

//ARC与非ARC混编

//#if __has_feture(objc_arc)

//ARC编译

//#else

//非ARC编译

//#endif

第二种表现形式:

// .h文件

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

// .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)shared##name \

{ \

static dispatch_once_t onceToken; \

dispatch_once(&onceToken, ^{ \

_instance = [[self alloc] init]; \

}); \

return _instance; \

} \

\

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

{ \

return _instance; \

}

//ARC与非ARC混编

//#if __has_feture(objc_arc)

//ARC编译

//#else

//非ARC编译

//#endif

.h文件中

#import <Foundation/Foundation.h>

@interface HMMovieTool : NSObject

HMSingletonH(MovieTool)

@end

.m文件中

#import "HMMovieTool.h"

@implementation HMMovieTool

HMSingletonM(MovieTool)

@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: