##Demo
从一个 demo 来感性认识一下 android 里面到处使用的 RefBase ,sp 和 wp 。
首先在 android 源码目录 external
中建立 weightpointer
目录。
在 weightpointer
目录建立 weightpointer.cpp
:::cpp
#include <stdio.h>
#include <utils/RefBase.h>
class WeightClass : public RefBase{
public:
void printRefCount(){
int32_t strong = getStrongCount();
weakref_type *ref = getWeakRefs();
printf("*********************\n");
printf("Strong Ref Count: %d\n", (strong == INITAL_STRONG_VALUE? 0:strong));
printf("Weak Ref Count: %d\n", ref->getWeakCount());
printf("*********************\n");
}
};
编写 WeightClass 其继承了 RefBase 。实现了一个叫做printRefCount
方法,作用就是通过调用 RefBase 相关接口,获得并打印生成对象的强引用和弱引用的信息。
###StrongClass
接着实现一个叫做 StrongClass
的类。
:::cpp
class StrongClass : public WeightClass{
public:
StrongClass(){
printf("Construct StrongClass Object \n");
}
virtual ~StrongClass(){
printf("Destroy StrongClass Object\n");
}
};
StrongClass
继承于 WeightClass
,实现了构造函数和析构函数。可以知道对象什么时候被创建和什么时候销毁。
接着,写测试方法和 main 方法测试 StrongClass。
:::cpp
void TestStrongClass(StrongClass *pStrongClass){
wp<StrongClass> wpOut = pStrongClass;
pStrongClass->printRefCount();
{
sp<StrongClass> spInner = pStrongClass;
pStrongClass->printRefCount();
}
sp<StrongClass> spOut = wpOut.promote();
printf("spOut: %p\n", spOut.get());
}
int main(int argc, char *argv[])
{
printf("Test Strong Class: \n");
StrongClass* pStrongClass = new StrongClass();
TestStrongClass(pStrongClass);
return 0;
}
运行结果
:::cpp
Test Strong Class:
Construct StrongClass Object
*********************
Strong Ref Count: 0
Weak Ref Count: 1
*********************
*********************
Strong Ref Count: 1
Weak Ref Count: 2
*********************
Destroy StrongClass Object
spOut: 0x0
让我们看一下程序是怎么运行的。进入 TestStrongClass
后,若引用指针 wpOut
指向了 pStrongClass
,这时候 RefBase
就开始帮我们计数了, 可以看到 Weak Ref Count
是1。
接着进入代码块。定义强引用指针 spInner
指向pStrongClass
。从 printRefCount
可以看出 强引用和弱引用分别加了一。接着退出代码块,这时 spInner
出栈被系统回收,同时我们看到 pStrongClass
被自动析构了,因为 RefBase 知道其强引用减为0 了。看,我们没有调用 delete ,对象自动就被析构了。这时调用 wpOut.promote()
会失败,spOut: 0x0
。因为对象已经销毁了。
###WeakClass
接着我们再写一个叫做 WeakClass 的测试类。
:::cpp
class WeakClass : public WeightClass{
public:
WeakClass(){
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
printf("Construct WeakClass Object \n");
}
virtual ~WeakClass(){
printf("Destroy WeakClass Object\n");
}
};
这个 WeakClass
同样继承了 WeightClass
,同样实现了构造函数和析构函数,不同的是在构造函数中增加了一个方法调用 extendObjectLifetime(OBJECT_LIFETIME_WEAK);
。 这个方法告诉 RefBase 这个类的生命周期是由弱引用来决定的。
接着编写测试方法
:::cpp
void TestWeakClass(WeakClass *pWeakClass){
wp<WeakClass> wpOut = pWeakClass;
pWeakClass->printRefCount();
{
sp<WeakClass> spInner = pWeakClass;
pWeakClass->printRefCount();
}
pWeakClass->printRefCount();
sp<WeakClass> spOut = wpOut.promote();
printf("spOut: %p.\n", spOut.get());
}
int main(int argc, char *argv[])
{
printf("\nTest Weak Class: \n");
WeakClass *pWeakClass = new WeakClass();
TestWeakClass(pWeakClass);
return 0;
}
其运行结果为
:::cpp
Test Weak Class:
Construct WeakClass Object
*********************
Strong Ref Count: 0
Weak Ref Count: 1
*********************
*********************
Strong Ref Count: 1
Weak Ref Count: 2
*********************
*********************
Strong Ref Count: 0
Weak Ref Count: 1
*********************
spOut: 0x4051f540.
Destroy WeakClass Object
可以看到,只要弱引用还在,对象就不会析构,wpOut
可以转成 spOut
。当退出这个函数,也就是弱引用置0时,对象才调用析构函数。同样析构是自动进行的。
##代码分析