Android 强弱引用

Android 强弱引用

软件:Source Insight 4.0、starUml

代码目录:

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

一、简介

从media服务的main函数入口中,可以发现

sp<ProcessState> proc(ProcessState::self());

sp其实就是强指针或强引用(strong pointer),与 sp 对应的是 wp,也就是弱指针或弱引用(weak pointer),Android Native 层(C++)中大量使用了sp/wp,了解sp/wp的源码及使用对理解Android Native层是很有帮助的。

智能指针最大的作用就是自动销毁对象。有这么一个场景,对象 A 和 对象 B 互相引用,系统无法回收这两个对象,任意回收其中一个对象,都会发现被另外一个对象引用,导致“死锁”无法回收,针对这种情况,可以使用强弱指针,对A对象使用强指针计数,对B对象使用弱指针计数,只要强指针计数为0,不管弱引用计数是否为0,都可以回收这个对象。一个对象只有弱指针引用时,必须升级为强指针,才能使用这个对象。

二、sp 源码分析

sp 强指针就是一个模板类,有点类似于Java的泛型,先看下 sp 的头文件 StrongPointer.h

template<typename T>
class sp {
   
public:
    inline sp() : m_ptr(0) {
    }

    sp(T* other);  // 方式1
    sp(const sp<T>& other); // 方式2
    sp(sp<T>&& other); // 方式3
    template<typename U> sp(U* other);  // NOLINT(implicit)
    template<typename U> sp(const sp<U>& other);  // NOLINT(implicit)
    template<typename U> sp(sp<U>&& other);  // NOLINT(implicit)

    ~sp();

    // Assignment

    sp& operator = (T* other); // 方式4
    sp& operator = (const sp<T>& other); // 方式5
    sp& operator = (sp<T>&& other); // 方式6

    template<typename U> sp& operator = (const sp<U>& other);
    template<typename U> sp& operator = (sp<U>&& other);
    template<typename U> sp& operator = (U* other);
    //! Special optimization for use by ProcessState (and nobody else).
    void force_set(T* other);
    // Reset
    void clear();
    // Accessors
    inline T&       operator* () const     {
    return *m_ptr; }
    inline T*       operator-> () const    {
    return m_ptr;  }
    inline T*       get() const            {
    return m_ptr; }
    inline explicit operator bool () const {
    return m_ptr != nullptr; }
    // Operators
    COMPARE(==)
    COMPARE(!=)
    COMPARE(>)
    COMPARE(<)
    COMPARE(<=)
    COMPARE(>=)
private:    
    template<typename Y> friend class sp;
    template<typename Y> friend class wp;
    void set_pointer(T* ptr);
    T* m_ptr;
};

2.1 sp 构造函数

【StrongPointer.h】

sp 初始化的方式有6种:

 sp(T* other);  // 方式1
 sp(const sp<T>& other); // 方式2
 sp(sp<T>&& other); // 方式3
 sp& operator = (T* other); // 方式4
 sp& operator = (const sp<T>& other); // 方式5
 sp& operator = (sp<T>&& other); // 方式6

具体方法如下:

方法1

template<typename T>
sp<T>::sp(T* other)
        : m_ptr(other) {
   
    if (other)
        other->incStrong(this);
}

方法2

template<typename T>
sp<T>::sp(const sp<T>& other)
        : m_ptr(other.m_ptr) {
   
    if (m_ptr)
        m_ptr->incStrong(this);
}

方法3

template<typename T>
sp<T>::sp(sp<T>&& other)
        : m_ptr(other.m_ptr) {
   
    other.m_ptr = nullptr;
}

方法4

template<typename T>
sp<T>& sp<T>::operator =(T* other) {
   
    T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
    if (other) other->incStrong(this);
    if (oldPtr) oldPtr->decStrong(this);
    if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
    m_ptr = other;
    return *this;
}

方法5

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值