【iOS开发】单例设计模式

来源:互联网 发布:防火墙软件 编辑:程序博客网 时间:2024/05/18 14:27
一、什么是单例:
 单例:在内存中只有唯一的实例,并且提供一个全局的访问方法!
  单例的好处:可以实现同一份资源共享。
 最常用的应用实例:音乐播放!

二、单例设计:非全部封死,提供两个创建对象的方式
(1)可以选择使用类方法,直接创建一个单例对象
(2)也可以选择使用其他方式,如alloc、init方式,创建非单例对象
在单例类的.m文件中:
+(instancetype)shareManager{    static id instance;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        instance = [[self alloc]init];    });    return instance;}

三、单例设计:全部封死,不论怎么创建,产生的都是单例对象
1、在ARC环境下,单例类.m文件:
static id _instance;@implementation HMAccount//提供一个类方法,快速创建单例对象+(instancetype)shareAccount{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        _instance = [[self alloc]init];    });    return _instance;}-(instancetype)init{       if (self = [super init]) {               static dispatch_once_t onceToken;        dispatch_once(&onceToken, ^{            //初始化代码        });    }    return self;}+(instancetype)allocWithZone:(struct _NSZone *)zone{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{               _instance = [super allocWithZone:zone];    });    return _instance;}

2、在MRC(非ARC)环境下,单例类.m文件:
static id _instance;@implementation HMAccount/** *  实现自定义方法,内部创建对象 */+ (instancetype)shareAccount{       static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{               _instance = [[self alloc]init];    });    return _instance;}/** *  重写init方法,保证初始化资源操作只做一次 */-(instancetype)init{    if (self = [super init]) {        static dispatch_once_t onceToken;        dispatch_once(&onceToken, ^{                       //加载资源,子控件等                   });    }    return self;}/** *  重写alloc方法,保证对象只创建一个,地址唯一 */+ (instancetype)allocWithZone:(struct _NSZone *)zone{    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{               _instance = [super allocWithZone:zone];    });    return _instance;}/** *  重写copy方法,内部创建对象 */+ (id)copyWithZone:(struct _NSZone *)zone{    return _instance;}/** *  重写release方法,不允许释放对象 */-(oneway void)release{}/** *  重写release方法,不允许释放对象 */-(instancetype)autorelease{    return _instance;}/** *  重写retain方法,不允许对象计数器+1 */-(instancetype)retain{    return _instance;}/** *  重写retain方法,不允许对象计数器+1 */-(NSUInteger)retainCount{    return 1;}

四、高效编程 —- 使用宏封装单例模型(以ARC下,全部封死的情况为例)
(1)新建一个.h文件,定义单例宏
#define singleton_h(name)  +(instancetype)share##name;#define singleton_m(name)\static id _instance;\+(instancetype)share##name\{\    static dispatch_once_t onceToken;\    dispatch_once(&onceToken, ^{\        _instance = [[self alloc]init];\    });\    return _instance;\}\+(instancetype)allocWithZone:(struct _NSZone *)zone\{\    static dispatch_once_t onceToken;\    dispatch_once(&onceToken, ^{\        _instance = [super allocWithZone:zone];\    });\    return _instance;\}

(2)使用
在需要设计成单例的类中:(Account类)
》 .h文件中:singleton_h(Account)
》 .m文件中:singleton_m(Account)

五、总结
1、在实际开发中根据实际需求选择是否需要全部封死
2、个人建议:使用第一种方法,不要全部封死,提供一个快速创建单例对象的方法就好了。
这样设计也是仿照苹果单例的设计模式,例如:
 UIApplication *app = [UIApplicationsharedApplication];
 UIApplication *app1 = [[UIApplicationalloc]init];
苹果设计的单例也是支持两种方式创建对象的。
【by:Leo_zzp,支持原创,转载请说明出处!】
      个人邮箱:15999745308@163.com,GitHub链接:MrLeoZou,期待您的交流!


0 0