美文网首页
3.设计模式之单例模式

3.设计模式之单例模式

作者: 王洛书 | 来源:发表于2016-08-06 18:29 被阅读0次

    1.目的:保证程序在运行过程中,一个类只有一个实例,且易于调用,只需要创建初始化一次,共享一份资源

    2.新创建一个类,如果对这个类多次初始化,便会得到多个类对象,分配多个内存空间,如果有‘初始化多次这个类,但是需要获得同一个对象’的需求,就要使用到单例设计模式实现。

    3.要实现每次初始化都得到同一个对象,就需要对alloc方法进行重写。但是不管是alloc还是allocWithZone最终都是调用的allocWithZone方法,所以只需要对allocWithZone方法进行重写就行了。

    4.代码实现:创建一个ETPerson类,实现NSCopying协议

    ETPerson.h

    + (instancetype)sharedPerson; //写一个类方法,进行类的初始化

    ETPerson.m

    static XMGPerson *_person;

    + (instancetype)allocWithZone:(struct _NSZone *)zone

    { //重写allocWithZone方法,需要先调用父类的方法实现,赋值给类对象,使用GCD一次性函数,保证程序运行期间只调用一次

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

    _person = [super allocWithZone:zone]; //不能直接return,需要调用父类方法,得到值,否则是空值

    });

    return _person;

    }

    + (instancetype)sharedPerson

    { //初始化,调用allocWithZone方法

    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{

    _person = [[self alloc] init];

    });

    return _person;

    }

    - (id)copyWithZone:(NSZone *)zone

    { //保证类对象进行复制时,得到的也是同一个对象,同一块内存地址,因为此时已经有了对象,有了值,所以直接return即可

    return _person;

    }

    5.单例宏:因为不论对几个类设计为单例,重写的方法和步骤都是一样的,所以可以抽出成宏在工程中调用,简单方便。

    Macro.h

    // .h文件

    #define ETSingletonH + (instancetype)sharedInstance;

    // .m文件

    #define ETSingletonM \

    static id _instace; \

    + (instancetype)allocWithZone:(struct _NSZone *)zone \

    { \

    static dispatch_once_t onceToken; \

    dispatch_once(&onceToken, ^{ \

    _instace = [super allocWithZone:zone]; \

    }); \

    return _instace; \

    } \

    + (instancetype)sharedInstance \

    { \

    static dispatch_once_t onceToken; \

    dispatch_once(&onceToken, ^{ \

    _instace = [[self alloc] init]; \

    }); \

    return _instace; \

    } \

    - (id)copyWithZone:(NSZone *)zone \

    { \

    return _instace; \

    }

    定义宏,代码需要写在一行,才不会报错,对于多行代码的宏定义,需要在每行代码的后面加一个\,这样下一行代码就会被识别到上一行,就不会报错了。

    以上的宏定义的类方法名,任何一个类调用,显示都是一样的,如果想实现不同类实现单例时,调用类方法名也显示不同,进行区分时,可以使用下面宏定义:

    6.自定义类方法名的宏定义

    // .h文件

    #define ETSingletonH(name) + (instancetype)shared##name;

    // .m文件

    #define ETSingletonM(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; \

    }

    --对.h文件宏定义做个解释:

    #define ETSingletonH(name) + (instancetype)shared##name;

    (name)调用者传入的自定义方法名;##是连接符 -- ##name会被替换为调用者传入的自定义方法名。

    相关文章

      网友评论

          本文标题:3.设计模式之单例模式

          本文链接:https://www.haomeiwen.com/subject/tbvksttx.html