您的位置:首页 > 职场人生

iOS单例模式(面试必考)

2015-08-23 12:32 316 查看
​# 单例模式(面试必考)

1. 单例模式的作用

可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问

从而方便地控制了实例个数,并节约系统资源

2. 单例模式的使用场合

在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)

3. ARC中,单例模式的实现

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

static id _instance;


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

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}


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

+ (instancetype)sharedInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}


4.实现copyWithZone:方法

- (id)copyWithZone:(struct _NSZone *)zone
{
return _instance;
}

4.ARC中完整版(GCD)

static id _instance;
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:zone] init]; // 记住这儿是super,不能用self
});

return _instance;
}

+ (instancetype)sharedPerson
{

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}

// copyWithZone方法的前提是必须先有一个对象
- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}


在实际开发中,一个应用程序可能有多个对象是单例对象,此时我们应该把
单例抽成一个宏放在一个单独的.h文件中
,
千万不能用继承


其中
\
表示此行跟下面一行是一起的

##
表示后面是参数

此时,注释只能在上面,在右边注释会报错的

// .h文件中的声明
#define SLInstanceH(name)  + (instancetype)shared##name;
// .m文件的实现
#define SLInstanceM(name) static id _instance; \
\
+ (instancetype)allocWithZone:(struct _NSZone *)zone\
{\
static dispatch_once_t onceToken;\
dispatch_once(&onceToken, ^{\
_instance = [[super allocWithZone:zone] init];\
});\
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;\
}


使用宏的时候

在.m文件中

#import <Foundation/Foundation.h>
#import "SLSharedInstance.h"  // 导入,定义了宏的.h文件

@interface SLPerson : NSObject<NSCopying>
SLInstanceH(Person)  // 传入单例的对象
@end


在.h文件中

#import "SLPerson.h"

@implementation SLPerson
SLInstanceM(Person)
@end

5. 单例模式(常规做法,非GCD)

一定要加互斥锁,不然会有线程安全问题

#import "SLPerson.h"

@implementation SLPerson
static id _instance;
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
@synchronized(self){ // 一定要加互斥锁,不然会有线程安全问题
if (_instance == nil) {
_instance = [[super allocWithZone:zone] init];
}
}
return _instance;
}
+ (instancetype)sharedPerson
{
@synchronized(self){
if (_instance == nil) {
_instance = [[self alloc] init];
}
}
return _instance;
}

// 要有对象才能进行copy
- (id)copyWithZone:(NSZone *)zone
{
return _instance;
}
@end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: