【iOS开发】单例设计模式

一、什么是单例:
 单例:在内存中只有唯一的实例,并且提供一个全局的访问方法!
  单例的好处:可以实现同一份资源共享。
 最常用的应用实例:音乐播放!

二、单例设计:非全部封死,提供两个创建对象的方式
(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,期待您的交流!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值