Android4.4 智能指针(RefBase, WP, SP)

来源:互联网 发布:java获取本周的第一天 编辑:程序博客网 时间:2024/05/18 07:16

1: 概述

智能指针的终极目标:  方便开发人员编写代码并且开发人员不必手动维护对象的生命周期。

示例:
1: 未使用智能指针的代码, 当New 出来一个对象的时候(对象保存在Heap区), 一定要记得delete这个对象。(忘记了就会导致内存泄露)
2: 对于使用智能指针的代码, New出来对象的回收, 完全由智能指针维护.

sp和wp的关系:

两个都是智能指针, 使用它俩之后, 对象的生命周期不用手动维护。

sp和wp的区别:

说到区别, 必须要说 继承的积累RefBase 有一个flag (OBJECT_LIFETIME_WEAK,OBJECT_LIFETIME_STRONG【默认使用】),
如果 flag == OBJECT_LIFETIME_STRONG,
那么生命周期由强指针维护, 当强指针的引用计数为0的时候, 则析构对象。
如果flsg == OBJECT_LIFETIME_WEAK,
那么生命周期由弱指针维护, 当弱指针的引用计数为0的时候(强指针的引用计数为0不析构), 才析构对象。

还有一个区别就是:
wp引用的对象不能直接使用。 原因: 假设  flag == OBJECT_LIFETIME_STRONG, 强指针为0而弱指针不为0的时候, 这个时候对象已经被析构了。
所以要使用wp, 必须把弱指针升级为强指针(sp<T> strongp = weakp.promote();)。  

2: RefBase, wp, sp类图

类图是从网上找的一张, 可以比较形象解读。


可以这样理解:
1: 所有想要使用智能指针的类都需要继承基类RefBase(RefBase 用来维护智能指针中的引用计数器的)。
2: sp<T> ,wp<T> 是智能指针, 它实现的原理是靠修改RefBase中的引用计数器来实现的。
3: 关键点也是我之前不理解的, 而其他的类似的文章也没说的, 智能指针是何时修改引用计数器的。
-- 首先 sp<T> sp = new T();  == sp<T> sp(new T()); 这样写的话就一目了然了
-- sp<T> sp 这里定义的是一个对象, 对象是存储在栈区的, 栈区的话肯定有入栈和出栈操作。 对应着 构造 和 析构函数。 而智能指针就是在构造和析构函数中去触发对引用计数的修改的。

3: 智能指针的原理

可能是我之前一直接触的Java, 不涉及内存释放的操作, 所以理解起来智能指针比较难。
如果懂了下面两个操作的区别, 那智能指针的最基本原理就掌握了。
1) A a;                        -- 内存分配在栈区 (内存在编译的时候已经分配好在栈区了)
2) A* a = new A();    -- 内存分配在堆区(记得new和delete是成对出现的就可以了)

4: sp和wp的创建过程主要涉及到incStrong() 和 incWeak()

sp 指针增加的时候调用incStrong(), 而incStrong()又默认调用incWeak()。 所以sp的指针计数器一定小于或等于wp的指针计数器。
wp指针增加的时候调用incWeak(), 仅仅增加weak的指针计数器。

5: sp和wp的析构过程主要涉及到decStrong() 和 decWeak()

先提一下指针计数器对象 weakref_type,  weakref_type一共维护了3个对象 :
1: mStrong (强指针计数器)
2: mWeak(弱指针计数器)
3: mFlags (标志对象由哪个指针计数器维护)

sp析构的时候调用decStrong(), 1: 首先强指针计数器减一 2: 如果强制镇计数器为0, 则释放智能指针引用的对象 3:弱指针计数器减一 4: 如果弱指针计数器为0, 则需要释放 weakref_type对象(这是正常使用的流程, 根据mFlags的不同, 以及sp是否初始化, 这个流程都会有所变化)

wp析构的时候调用decWeak(), 1: 首先弱指针计数器减一 2: 如果弱指针计数器为0, 则释放智能指针引用的对象 3: 最后再释放weakref_type对象  (这是正常使用的流程, 根据mFlags的不同, 以及wp是否初始化, 这个流程都会有所变化)

6: wp指针的使用介绍( 主要涉及到attemptIncStrong() )

wp不能直接使用, 因为它不能保证引用的对象是否被释放, 所以wp使用之前一定要调用promote方法, 把wp转换成sp。

promote的主要实现逻辑在attemptIncStrong中。


最后附上一张自己画的草图, 一般人看不懂。


0 0
原创粉丝点击