ios--单例模式

ios单例模式

一、什么是单例模式

官方解释

保证一个类只有一个实例,并且提供一个全局的访问入口访问这个实例。

一个类必须只有一个对象。客户端必须通过一个众所周知的入口访问这个对象。

这个唯一的对象需要扩展的时候,只能通过子类化的方式。客户端的代码能够不需要任何修改就能够使用扩展后的对象。

初读是不是一头雾水,emm,我也是,呐,看完单例模式的用处再跟你解释。

二、单例模式的用处

主要用在封装网络请求播放器存放常用数据等。

仔细想想,你做网络请求时如果不是用单例模式,是不是每次网络请求时都要alloc个对象,然后调用方法请求?拜托,你alloc多了系统资源被占用过多,性能低下,我靠,那还开发个屁,所以这个时候单例模式就能很好的帮助我们解决这个问题,故你可以这样来看待单例模式:

单例在整个工程中,就相当于一个全局变量,就是不论在哪里需要用到这个类的实例变量,都可以通过单例方法来取得,而且一旦你创建了一个单例类,不论你在多少个界面中初始化调用了这个单例方法取得对象,它们所有的对象都是指向的同一块内存存储空间(即单例类保证了该类的实力对象是唯一存在的一个)。

注意加粗和斜体字体哦,多读几遍!!!!

三、那如何使用单例模式呢?

 + (DJSingleton *)shareInstance{
         static DJSingleton * s_instance_dj_singleton = nil ;//设置静态变量,隔离外部修改
         if (s_instance_dj_singleton == nil) {
             s_instance_dj_singleton = [[DJSingleton alloc] init];
        }
     return (DJSingleton *)s_instance_dj_singleton;
 }
 
四、可是多线程情况下呢?
+ (DJSingleton *)shareInstance{
    static DJSingleton * s_instance_dj_singleton = nil ;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (s_instance_dj_manager == nil) {
            s_instance_dj_manager = [[DJSingleton alloc] init];
        }
    });
    return (DJSingleton *)s_instance_dj_singleton;
}
五、那再调用alloc呢?

看起来很完美了。可是Objective-C毕竟是Objective-C。别的语言,诸如C++,java,构造方法可以隐藏。Objective-C中的方法,实际上都是公开的,虽然我们提供了一个方便的工厂方法的访问入口,但是里面的alloc方法依旧是可见的,可以调用到的。也就是说,虽然你给了我一个工厂方法,调皮的小伙伴可能依旧会使用alloc的方式创建对象。这样会导致外面使用的时候,依旧可能创建多个实例。

关于这个事情的处理,可以分为两派。一个是冷酷派,技术上实现无论你怎么调用,我都给你同一个单例对象;一个是温柔派,是从编译器上给调皮的小伙伴提示,你不能这么造对象,温柔的指出有问题,但不强制约束。

1. 冷酷派的实现

冷酷派的实现从OC的对象创建角度出发,就是把创建对象的各种入口给封死了。alloc,copy等等,无论是采用哪种方式创建,我都保证给出的对象是同一个。

由Objective-C的一些特性可以知道,在对象创建的时候,无论是alloc还是new,都会调用到 allocWithZone方法。在通过拷贝的时候创建对象时,会调用到-(id)copyWithZone:(NSZone *)zone,-(id)mutableCopyWithZone:(NSZone *)zone方法。因此,可以重写这些方法,让创建的对象唯一

+(id)allocWithZone:(NSZone *)zone{
    return [DJSingleton sharedInstance];
}
+(DJSingleton *) sharedInstance{
    static DJSingleton * s_instance_dj_singleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        s_instance_dj_singleton = [[super allocWithZone:nil] init];
    });
    return s_instance_dj_singleton;
}
-(id)copyWithZone:(NSZone *)zone{
    return [DJSingleton sharedInstance];
}
-(id)mutableCopyWithZone:(NSZone *)zone{
    return [DJSingleton sharedInstance];
}

2. 温柔派的实现

温柔派就直接告诉外面,alloc,new,copy,mutableCopy方法不可以直接调用。否则编译不过。


+(instancetype) alloc __attribute__((unavailable("call sharedInstance instead")));
+(instancetype) new __attribute__((unavailable("call sharedInstance instead")));
-(instancetype) copy __attribute__((unavailable("call sharedInstance instead")));
-(instancetype) mutableCopy __attribute__((unavailable("call sharedInstance instead")));

六、最后

这里有两篇比较好文章,同时本篇内容也摘抄了其中。

iOS中的单例模式

iOS 单例模式,你真的写对了吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值