单例的完整实现

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




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值