Android系统之智能指针sp和wp回顾

概述

Android中的智能指针是对C++中的对象回收机制的封装,C++中的构造函数和析构函数是在对象new出来和delete的时候调用的,但是一个在销毁一个对象的时候,我们需要手动的调用delete关键字来销毁,但是在Java中我们无需在乎这些对象的销毁工作,都是由垃圾回收器来做了,所以在Android系统层,为了达到Java的这个自动管理对象的效果,就出现了智能指针的概念了,他的出现类似于Java中的回收器

内部实现也很简单,就是用两个变量来控制,一个是强引用计数变量,一个是弱引用计数变量,这两个变量都是int类型的,表示一个对象被引用多少次,两个变量会依据具体的生命管理周期模式来决定是否释放对象。

android/system/core/libutils/RefBase.cpp
android/system/core/libutils/include/utils/RefBase.h
android/system/core/libutils/include/utils/StrongPointer.h

RefBase

Android设计了基类RefBase,用以管理引用数,所有类必须从RefBase派生,RefBase是所有对象的始祖。

设计模板类sp、wp,用以引用实际对象,sp强引用和wp弱引用。sp、wp声明为栈对象,作用域结束时,自动释放,自动调用析构函数。因此,可以在sp、wp的构造函数中,增引用数;在析构函数中,减少引用计数。

专门设计weakref_impl类,该类是RefBase的内部类,用来做真正引用数管理,创建实际对象时,同时创建一个mRefs对象。不管是强引用和弱应用,都由mRefs来管理。

智能指针的实现


如果一个类想使用智能指针,那么必须满足下面两个条件:

a. 该类是虚基类RefBase的子类或间接子类
b. 该类必须定义虚构造函数。如virtual ~MyClass();

实际对象的释放,可分为强引用控制和弱引用控制。所谓强引用控制,指的是强引用数mStrong为0时,释放实际对象;弱引用控制,则指的是弱引用数mWeak为0时,才释放实际对象。

class Sheep: public RefBase { // 羊年,定义Sheep从RefBase派生  
public:  
       Sheep(): RefBase() { }// 可显示调用RefBase的构造,也可以不用  
       virtual~Sheep() { }// 最好声明为virtual,以便从Sheep派生  
};  
void testSheep() {  
       Sheep*pSheep = new Sheep(); // new一个Sheep对象,这个是一个堆对象  
       { // 限定sp的作用域  
              sp<Sheep>spSheep(pSheep); // spSheep是一个栈对象  
              {// 限定wp的作用域  
                     wp<Sheep>wpSheep(pSheep);  
              }//调用wp的析构函数  
       } // 调用sp的析构函数,实际对象pSheep已释放,若再使用pSheep将会出错  
} 

RefBase构造和mRefs

在实例代码中,我们先定义了一个类Sheep,从RefBase派生,创建了一个实际对象,pSheep 指向实际对象。

在构造Sheep的实际对象时,将调RefBase的构造函数。RefBase的构造函数如下,在构造函数中创建mRefs。

weakref_impl从weakref_type派生,mRefs才是真正的“管家”。


RefBase::RefBase()  
    :mRefs(new weakref_impl(this)) // 真正管理引用计数  
{}  
weakref_impl(RefBase* base)  
    :mStrong(INITIAL_STRONG_VALUE) // 1<<28(268435456),为什么不是0?  
    ,mWeak(0)  
    ,mBase(base) // mBase指向实际对象  
    ,mFlags(0) // 这个标识很重要,指定是强应用控制还是弱引用控制  
{}  

请注意这里的mFlags,默认值为0,可通过修改这个标志来设置是强引用控制,还是弱引用控制,代码如下:

扫描二维码关注公众号,回复: 889718 查看本文章
//system/core/include/utils/RefBase.h
enum {  
   OBJECT_LIFETIME_STRONG  = 0x0000,  
   OBJECT_LIFETIME_WEAK    = 0x0001,  
   OBJECT_LIFETIME_MASK    = 0x0001  
}; 

mFlags默认为0,即OBJECT_LIFETIME_STRONG,强引用控制。设置为OBJECT_LIFETIME_WEAK时,为弱引用控制。可以通过extendObjectLifetime函数修改,代码如下

//system/core/libutils/RefBase.cpp
void RefBase::extendObjectLifetime(int32_t mode)  
{  
   android_atomic_or(mode, &mRefs->mFlags);  
}  

猜你喜欢

转载自blog.csdn.net/ch853199769/article/details/80314202