Strong pointer and weak pointer basis

Smart Pointers in Android include: lightweight Pointers, strong Pointers, weak Pointers. Strong Pointers: It maintains the life cycle of an object primarily through strong reference counting. Weak Pointers: They maintain the life cycle of the object they point to primarily through weak reference counting.

If strong or weak Pointers are used in a class, the class must inherit from RefBase, because strong and weak Pointers are the reference counters that are implemented through the RefBase class.

Strong and weak Pointers are more intimate than lightweight Pointers, so they are usually used together.

Strong pointer principle analysis

The following source code analysis is derived from the android5.0 system source code strong pointer definition implementation mainly in \frameworks\rs\ CPP \util\RefBase. H file

class RefBase
{
public:
            // Defines member variables used to maintain reference counts for strongly referenced objects
            void            incStrong(const void* id) const;
            // Defines member variables used to maintain reference counts for strongly referenced objects
            void            decStrong(const void* id) const;
          
            void            forceIncStrong(const void* id) const;

            // Get the number of strong pointer counts.
            int32_t         getStrongCount(a) const;
    // This class implements counters
    class weakref_type
    {
    public:
        RefBase*            refBase(a) 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(a) const;

        / /! DEBUGGING ONLY: Print references held on object.
        void                printRefs(a) 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(a) const;

            / /! DEBUGGING ONLY: Print references held on object.
    inline  void            printRefs(a) const { getWeakRefs() - >printRefs(a); }/ /! DEBUGGING ONLY: Enable tracking of object.
    inline  void            trackMe(bool enable, bool retain)
    {
        getWeakRefs() - >trackMe(enable, retain);
    }

    typedef RefBase basetype;

protected:
                            RefBase(a);virtual                 ~RefBase(a);/ /! 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(a);
    virtual void            onLastStrongRef(const void* id);
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
    virtual void            onLastWeakRef(const void* id);

private:
    friend class ReferenceMover;
    static void moveReferences(void* d, void const* s, size_t n,
            const ReferenceConverterBase& caster);

private:
    friend class weakref_type;
    // Get counter data from the class object.
    class weakref_impl;

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

        weakref_impl* const mRefs;
};

Copy the code

According to the above class definition, it can be seen that there is a nested WeakRef_type class inside the RefBase class. The weakRef_type class also describes the reference count of the object mRefs. That is, each RefBase object contains a WeakRef_type object.

Virtual is a virtual function.

conclusion

If an object’s lifecycle control flag is set to 0, the system will automatically release the object as long as its strong reference count is also set to 0.