iOS 开发

单例模式和GCD单例实现

2016-07-28  本文已影响326人  Mr丶炎

1、传统单例模式
2、GCD单例模式
3、用宏实现GCD单例模式
4、用宏实现GCD单例模式,名称随类名变化而变化

单例模式一旦使用,将永远不死。不管是控制器还是类,尽管push,pop还是dismiss都不会死掉,下一次用到时还是第一次创建的那个类。

1、看看传统单例模式的实现,要确保线程安全,一定要锁起来。

// static 修饰的对象,只有在程序结束对才会被释放
static id person;

/**
 创建单例的步骤
 1.保留一个单例对象的静态实例
 2.声明和实现一个类方法,返回一个有值的该类对象
 3.重写allocWithZoon方法,做判空处理
 */

// 单例的类方法命名一般用share+当前类名
+ (instancetype)sharedPerson {
    
    // synchronized能保证里面的内容同时只能被一个线程执行
    @synchronized(self) {
        
        // 先判断是否为空,如果为空再创建
        if (person == nil) {
            person = [[self alloc] init];
        }
    }
    
    return person;
}

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

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

2、看看GCD实现,我们用的是once函数,它已经确保了线程安全问题

static Car *_car;

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

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

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

3、用宏实现GCD单例模式,当我们需要实现单例类时,其实代码完全是一样的,这样我们抽成宏,但是这个我们只能用同一的方法,sharedInstance。如果我们想这样,一个person类,那么单例就是sharedPerson,看第四份代码。这里\作用是,让宏识别到后面的代码,因为宏默认只识别它后面一行代码,加\就代表下一行也是

// .h文件
#define SingletonH  + (instancetype)sharedInstance;

// .m文件
#define SingletonM \
\
static id _instance;\
\
+ (instancetype)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、用宏实现GCD单例模式,名称随类名变化而变化。这里需要注意,name都是传过来的,所有在用时.h和.m都要传name

像这样
SingletonH(Car)
SingletonM(Car)

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

// .m文件
#define SingletonM(name) \
\
static id _instance;\
\
+ (instancetype)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;\
}
上一篇下一篇

猜你喜欢

热点阅读