关于weak要了解的基本内容:
weak的使用场景: weak 的常见场景是在 delegate,block,NSTimer 中使用,我们经常用weak来避免以上场景中易产生的循环引用的问题.
weak的实际作用是:弱引用,在对象释放后置为 nil,避免错误的内存访问.也就是说:weak 可以在不增加对象的引用计数的同时,又使得指针的访问是安全的.
单例模式在OC和Swift这经常会被用到,好用的小模块工具类、很多SDK的初始化等等.但是这些单例的使用场景里都有一个共同的毛病,单例在被创建之后会伴随着进程一直存活,有时候我们的业务需求,特别是对于前端来说的话,很多单例模式的使用都是为了方便,所以我们其实很想在这些单例不必要存在的时候将它们释放掉,因为这些单例在一定程度上是有内存浪费的.
一个简单的例子:比如登陆模块的 LoginInstance 单例,我们在登陆之后除非需要二次登陆,不然就可能再也用不到这个单例了,我们最好的处理方式是将这个单例释放掉在登陆之后,而在登陆的过程当中我们随时随地的获取和使用这个单例,似乎这样的应用场景在前端开发中显得更多以及更常用,也似乎更佳的合理,更好的符合前端的性能尽可能的高的这种默认标准.
可是常规的单例模式无法实现上述需求,我们只能做到随时随地的获取使用这个单例,而无法释法这个单例.
那么,用weak试一下吧.
弱单例模式的 weak singleton 的具体实现代码如下
+ (id)sharedInstance {
static __weak ASingletonClass *instance;
ASingletonClass *strongInstance = instance;
@synchronized(self) {
if (strongInstance == nil) {
strongInstance = [[[self class] alloc] init];
instance = strongInstance;
}
}
return strongInstance;
}
这种特殊的单例有一个有意思的特性:在所有使用该单例的对象都释放后,单例对象本身也会自己释放.
如果 viewController A、B、C 三个视图控制器都调用了上面所描述的这种弱引用的弱单例模式.并且 viewController A、B、C 都持有 ASingletonClass 的强引用,一旦 A,B,C 都销毁后,这个单例就跟着销毁,而这个就跟我们之前的单例模式不一样了,它不会是从创建后就只能一直存在,无法释放.
这样我们再一次回到上述的登陆模块的时候,当我们的登陆控制器在棧里被释放掉之后,登陆的LoginInstance 单例也会随即释放,这样就达到了我们想要的效果.
此外重要的是:当 LoginInstance 再次被调用时,LoginInstance 又会重新被创建.这样二次登陆的时候,LoginInstance 还是一个单例.
然而我们会发现:weak singleton 这种弱单例模式中的 weak ,有着很漂亮的作用,巧妙的利用了weak的作用来设计了一种我们很想要的效果的模式,从而也看出来,对于关键词weak而言,还有很多能发现的美.