首页 > 学院 > 开发设计 > 正文

B1-单例实现(单例宏)

2019-11-14 19:39:49
字体:
来源:转载
供稿:网友

一、什么是单例

     单例就是,一个类,每次创建都是同一个对象。也就是说只能实例化一次。

二、如何保证每次创建都是同一个对象

     创建一个对象归根揭底都会经过一个途径,alloc方法(alloc方法会调用allocWithZone:)。因此只要保证alloc方法只会调用一次,且保证线程安全,然后把此对象放在静态区。以后不管是创建对象还是copy对象都直接返回静态区的对象。

三、注意点

     静态全局变量不需要考虑释放的问题(适用于MRC),解决线程安全问题可以用互斥锁或者GCD,后者更好。

     也可设置不让对象重复初始化,即让初始化方法只能执行一次。

四、具体实现代码如下

@implementation myManagerstatic id instance;+ (instancetype)allocWithZone:(struct _NSZone *)zone{    // 1、互斥锁//        @synchronized (self) {//            if (instance == nil)//            {//                instance = [super allocWithZone:zone];//            }//        }        // 2、GCD,只执行一次    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        if (instance == nil)        {            instance = [super allocWithZone:zone];        }    });    return instance;}+ (instancetype)sharedSoundTools{    instance = [[self alloc] init];    return instance;}- (id)copyWithZone:(NSZone *)zone{    return instance;}#PRagma mark - MRC 部分代码- (oneway void)release{    // 什么都不做}- (instancetype)retain{    // 本想什么都不做,但它要返回值    return instance;}- (instancetype)autorelease{    return instance;}- (NSUInteger)retainCount{    // 此处防止有人不明就里的粗暴释放对象,比如while循环    return ULONG_MAX;}- (instancetype)init{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{                self = [super init];        if (self)        {            self.age = 10; // 只是举个例子,只初始化一次,可以不设置        }    });    return self;}@end

 

五、单例宏

      以下代码写在单独singleton.h文件里,使用时直接包含.h头文件。

      使用方法,.h文件:singletonInterface(myManager);

                    .m文件:singletonImplementation(myManager);

      抽取代码如下:

#define singletonInterface(className)          + (instancetype)shared##className;#if __has_feature(objc_arc)// 以下是ARC版本#define singletonImplementation(className) /+ (instancetype)allocWithZone:(struct _NSZone *)zone { /    static dispatch_once_t onceToken; /    dispatch_once(&onceToken, ^{ /        if (instance == nil) { /            instance = [super allocWithZone:zone]; /        } /    }); /    return instance; /} /+ (instancetype)shared##className { /    static dispatch_once_t onceToken; /    dispatch_once(&onceToken, ^{ /        instance = [[self alloc] init]; /    }); /    return instance; /} /- (id)copyWithZone:(NSZone *)zone { /    return instance; /}#else// 以下是MRC版本#define singletonImplementation(className) /+ (instancetype)allocWithZone:(struct _NSZone *)zone { /    static dispatch_once_t onceToken; /    dispatch_once(&onceToken, ^{ /        if (instance == nil) { /            instance = [super allocWithZone:zone]; /        } /    }); /    return instance; /} /+ (instancetype)shared##className { /    static dispatch_once_t onceToken; /        dispatch_once(&onceToken, ^{ /        instance = [[self alloc] init]; /    }); /    return instance; /} /- (id)copyWithZone:(NSZone *)zone { /    return instance; /} /- (oneway void)release {} /- (instancetype)retain {return instance;} /- (instancetype)autorelease {return instance;} /- (NSUInteger)retainCount {return ULONG_MAX;}#endif// 提示末尾一行不要有 /

 

六、单例的两种模式
     1、懒汉式,是在需要的时候再加载到内存。
     2、饿汉式,会在最早的时间就把单例创建好,放入内存,随时可以使用。

// 饿汉式@implementation HMSoundToolsstatic id instance;// 只要程序运行,就会执行一次+ (void)load {    instance = [[self alloc] init];}// 第一次用到类或者子类的时候,会执行一次//+ (void)initialize {//    //}+ (instancetype)sharedSoundTools {    return instance;}- (id)copyWithZone:(NSZone *)zone {    return instance;}

 

 
 

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表