Android 智能指针学习笔记(二,完结) —— 强指针,弱指针

本文是关于Android智能指针的学习笔记,主要探讨了强指针和弱指针的实现原理,包括RefBase类在强弱指针中的作用,以及它们的应用实例。通过源码分析,详细阐述了强引用和弱引用计数的增减过程,并展示了如何在实际场景中使用这两种指针。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 上一篇学习了轻量级指针,而这一篇则要把强指针与弱指针的原理都探个究竟。
  • 关于智能指针的学习笔记,在这一篇也就完结了,总的来说内容是挺少的,不过其中有些逻辑还是需要细细琢磨才能理解的。

NOTE

  • 参考源码版本:Android 7.1.2。
  • 以下代码追踪思路均参考《Android 系统源代码情景分析(修订版)》

强指针和弱指针

1. 强指针实现原理

1.1 RefBase.h

  • 位置:system/core/include/utils/RefBase.h
  • 如果一个类对象要支持强弱指针,就必须继承 RefBase 类。
  • RefBase 类提供了强计数器与弱计数器。
  • Class RefBase
    • 利用 weakref_impl 对象 mRefs 来描述对象的引用计数。
    • weakref_impl 继承自 RefBase 的内部类 weakref_type
    • incStrongdecStrong 仍为计数操作。
    • 内部类 weakref_type
      • incWeak() / decWeak():弱引用计数操作。
      • attemptIncStrong() / attemptDecStrong():强引用计数操作。
class RefBase
{
public:
            void            incStrong(const void* id) const;
            void            decStrong(const void* id) const;

            void            forceIncStrong(const void* id) const;

            //! DEBUGGING ONLY: Get current strong ref count.
            int32_t         getStrongCount() const;

    class weakref_type
    {
    public:
        RefBase*            refBase() const;

        void                incWeak(const void* id);
        void                decWeak(const void* id);

        // acquires a strong reference if there is already one.
        bool                attemptIncStrong(const void* id);

        // acquires a weak reference if there is already one.
        // This is not always safe. see ProcessState.cpp and BpBinder.cpp
        // for proper use.
        bool                attemptIncWeak(const void* id);

        //! DEBUGGING ONLY: Get current weak ref count.
        int32_t             getWeakCount() const;

        //! DEBUGGING ONLY: Print references held on object.
        void                printRefs() const;

        //! DEBUGGING ONLY: Enable tracking for this object.
        // enable -- enable/disable tracking
        // retain -- when tracking is enable, if true, then we save a stack trace
        //           for each reference and dereference; when retain == false, we
        //           match up references and dereferences and keep only the 
        //           outstanding ones.

        void                trackMe(bool enable, bool retain);
    };

            weakref_type*   createWeak(const void* id) const;

            weakref_type*   getWeakRefs() const;

            //! DEBUGGING ONLY: Print references held on object.
    inline  void            printRefs() const { getWeakRefs()->printRefs(); }

            //! DEBUGGING ONLY: Enable tracking of object.
    inline  void            trackMe(bool enable, bool retain)
    {
        getWeakRefs()->trackMe(enable, retain);
    }

    typedef RefBase basetype;

protected:
                            RefBase();
    virtual                 ~RefBase();

    //! Flags for extendObjectLifetime()
    enum {
        OBJECT_LIFETIME_STRONG  = 0x0000,
        OBJECT_LIFETIME_WEAK    = 0x0001,
        OBJECT_LIFETIME_MASK    = 0x0001
    };

            void            extendObjectLifetime(int32_t mode);

    //! Flags for onIncStrongAttempted()
    enum {
        FIRST_INC_STRONG = 0x0001
    };

    virtual void            onFirstRef();
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
    virtual void            onLastWeakRef(const void* id);

private:
    friend class weakref_type;
    class weakref_impl;

                            RefBase(const RefBase& o);
            RefBase&        operator=(const RefBase& o);

private:
    friend class ReferenceMover;

    static void renameRefs(size_t n, const ReferenceRenamer& renamer);

    static void renameRefId(weakref_type* ref,
            const void* old_id, const void* new_id);

    static void renameRefId(RefBase* ref,
            const void* old_id, const void* new_id);

    weakref_impl* const mRefs;
};

1.2 RefBase.cpp

  • 位置:./system/core/libutils/RefBase.cpp
  • Class weakref_impl
    • 注意宏定义 DEBUG_REFS,它控制是否进入调试版本,我们只关注非调试。
    • 继承自 RefBase::weakref_type
    • mStrong 描述强引用计数。
    • mWeak 描述弱引用计数。
    • mBase 指向所引用的对象地址。
    • mFlags 描述对象的生命周期控制方式:
      • OBJECT_LIFRTIME_STRONG:只受强引用计数影响。
      • OBJECT_LIFETIME_WEAK:同时受强弱计数影响。
      • OBJECT_LIFETIME_MASK:似乎是用来做 & 操作,取最后一位。
      • 注意后两个的值是一样的。
class RefBase::weakref_impl : public RefBase::weakref_type
{
public:
    std::atomic<int32_t>    mStrong;
    std::atomic<int32_t>    mWeak;
    RefBase* const          mBase;
    std::atomic<int32_t>    mFlags;

#if !DEBUG_REFS

    weakref_impl(RefBase* base)
        : mStrong(INITIAL_STRONG_VALUE)
        , mWeak(0)
        , mBase(base)
        , mFlags(0)
    {
    }

    void addStrongRef(const void* /*id*/) { }
    void removeStrongRef(const void* /*id*/) { }
    void renameStrongRefId(const 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值