ios 单例实现方式

在开发中经常会用到单例,它在整个程序的运行周期里面只会被创建一次,只要程序没有结束,它就不会被释放!创建单例的两种方式如下:

一、GCD方式创建单例

static id _instance;

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToke;
    dispatch_once(&onceToke, ^{
        
        _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;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
    return _instance;
}


二、互锁创建单例的方法

static id _instance;

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [super allocWithZone:zone];
        }
    }
    return _instance;
}

+ (instancetype)sharedInstance
{
    @synchronized(self) {
        if (_instance == nil) {
            _instance = [[self alloc] init];
        }
    }
    return _instance;
}

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

- (id)mutableCopyWithZone:(NSZone *)zone
{
    return _instance;
}

说明

1、CGD创建单例的方式中,用dispatch_once保证了里面的代码只能被执行一次,如果程序再次走到这个方法的时候会直接返回创建好的实例对象,这样保证了只会创建一个实例对象;

2、 在互锁创建单例的方式中,@synchronized相当于给括起来的任务加了一把锁,如果当前任务正在执行,另外一条线程执行到@synchronized时候就会进入睡眠模式,等当前任务执行完后才会执行,此时_instance已经被创建,不为nil,所以直接返回_instance,这样也保证了只会创建一个实例对象。但是在多线程开发中,这种方式会影响程序的性能,建议用第一种


总结

在多线程开发中互锁的方式会影响项目的性能,建议用GCD的方式!


通过GCD创建单例的方式是固定不变的,为了方便以后快速实现单例,可以把创建方式定义成宏。

// .h文件
#define singleton_h(name) + (instancetype)shared##name;

// .m文件
#define singleton_m(name) \
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:(struct _NSZone *)zone \
{ \
return _instance; \
}\
\
- (id)mutableCopyWithZone:(NSZone *)zone\
{\
    return _instance;\
}

你可能感兴趣的:(OC笔记)