Android-RefBase&sp&wp

本贴最后更新于 3487 天前,其中的信息可能已经沧海桑田

最近在读 android 源码,学到不少有用的东西,写篇博文记录一下。

首先介绍一下 RefBase,sp,wp:

RefBase是所有对象的鼻祖类似于Java中的Object,它结合了sp和wp,实现了一套通过引用计数的方法来控制对象生命周期的机制。那么sp和wp分别是什么呢?网上有很多资料把他们解释为smart pointer,也就是智能指针,其实并不准确。其实sp就是strong pointer,wp则是weak pointer,分别叫做强指针和弱指针。下面通过源码来具体介绍一下:


RefBase::RefBase():mRefs(new weakref_impl(this)){}



这是RefBase的构造函数,它给成员变量mRefs赋值为weakref_impl类型对象,暂且把它叫做影子对象。


weakref_impl(RefBase* base):mStrong(INITIAL_STRONG_VALUE)//强引用计数,初始值0x1000000
                           ,mWeak(0) //弱引用计数,初始值0
                           ,mBase(base) //
                           ,mFlags(0)
                           ,mStringRefs(NULL)
                      {}


可以看到一个RefBase对象中包含了一个影子对象,影子对象里包含了强弱引用计数。下面看sp对象:


sp<T>::sp(T* other):m_ptr(other)
{
  if(other) other->incStrong(this);
}
sp对象需要用RefBase对象来初始化,所以other就是RefBase所代表的对象了。接着看RefBase类中的 incStrong函数。


void RefBase::incStrong(const void* id) const
{
  weakref_impl* const refs=mRefs;
  refs->addWeakRef(id);
  refs->incWeak(id);
  ......
  refs->addStrongRef(id);
  const int32_t c=android_atomic_inc(&refs->mStrong);//原子+1操作,返回旧值,即参数+1,返回+1前的值
  if(c!=INITIAL_STRONG_VALUE){
    return;
  }
  android_atomic_add(-INITIAL_STRONG_VALUE,&refs->mStrong);//原子加,参数相加
  const_cast<RefBase*>(this)->onFirstRef();
}


意图很明显,sp对象初始化后,影子对象的弱引用计数0+1=1,强引用计数变为1。

看完sp的构造之后,来看一下wp的构造


wp<T>::wp(const sp<T>& other):m_ptr(other.m_ptr)
{
  if(m_ptr){
    m_refs=m_ptr->createWeak(this);
  }
}


wp的用sp对象初始化,所以other是sp的对象,m_ptr指向的是实际对象。createWeak之后,跟刚才一样,弱引用计数+1,所以现在mWeak=2 mStrong=1。

下面看一下wp的析构函数


wp<T>::~wp()
{
  if(m_ptr) m_refs->decWeak(this);
}



调用的是RefBase对象的decWeak()函数。主要作用就是弱引用计数-1,即从2变成1。

接着sp的析构:



 if(m_ptr) m_ptr->decStrong(this);



这里把强引用计数和弱引用计数都变成0了。由于是否delete是根据强弱引用计数来判断的,所以实际对象和影子对象都被delete掉。强引用计数为0,实际对象被delete,弱引用计数为0,影子对象被delete。


这就是比较基本的RefBase、sp、wp的关系啦,其实对象的生命周期,还有其他的因素,不过都是围绕这三个对象和强弱引用计数来进行的。



  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    335 引用 • 324 回帖
  • RefBase
    1 引用 • 2 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 714593351

    哈哈,.top 域名啊,我那时候也注册了两个

  • wind
    作者

    @714593351 原来发布的博客会同步到社区里来==,今天第一次用呢。。。

推荐标签 标签

  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    179 引用 • 818 回帖
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 53 关注
  • 链滴

    链滴是一个记录生活的地方。

    记录生活,连接点滴

    169 引用 • 3834 回帖 • 1 关注
  • App

    App(应用程序,Application 的缩写)一般指手机软件。

    91 引用 • 384 回帖
  • RESTful

    一种软件架构设计风格而不是标准,提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

    30 引用 • 114 回帖 • 5 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    5 引用 • 7 回帖 • 1 关注
  • 微软

    微软是一家美国跨国科技公司,也是世界 PC 软件开发的先导,由比尔·盖茨与保罗·艾伦创办于 1975 年,公司总部设立在华盛顿州的雷德蒙德(Redmond,邻近西雅图)。以研发、制造、授权和提供广泛的电脑软件服务业务为主。

    8 引用 • 44 回帖 • 2 关注
  • danl
    164 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 1 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    295 引用 • 750 回帖
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖 • 1 关注
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 210 关注
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    364 引用 • 1840 回帖 • 2 关注
  • RemNote
    2 引用 • 16 回帖 • 12 关注
  • Unity

    Unity 是由 Unity Technologies 开发的一个让开发者可以轻松创建诸如 2D、3D 多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

    25 引用 • 7 回帖 • 138 关注
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 75 关注
  • 电影

    这是一个不能说的秘密。

    122 引用 • 608 回帖 • 1 关注
  • 新人

    让我们欢迎这对新人。哦,不好意思说错了,让我们欢迎这位新人!
    新手上路,请谨慎驾驶!

    52 引用 • 228 回帖 • 1 关注
  • Word
    13 引用 • 40 回帖
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖
  • 叶归
    5 引用 • 16 回帖 • 9 关注
  • Hibernate

    Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。

    39 引用 • 103 回帖 • 721 关注
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 174 关注
  • 区块链

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。所谓共识机制是区块链系统中实现不同节点之间建立信任、获取权益的数学算法 。

    92 引用 • 752 回帖 • 1 关注
  • 导航

    各种网址链接、内容导航。

    43 引用 • 177 回帖 • 3 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 394 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    179 引用 • 408 回帖 • 488 关注