




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、Android中通過(guò)引用計(jì)數(shù)來(lái)實(shí)現(xiàn)智能指針,并且實(shí)現(xiàn)有強(qiáng)指針與弱指針。由對(duì)象本身來(lái)提供引用計(jì)數(shù)器,但是對(duì)象不會(huì)去維護(hù)引用計(jì)數(shù)器的值,而是由智能指針來(lái)管理。要達(dá)到所有對(duì)象都可用引用計(jì)數(shù)器實(shí)現(xiàn)智能指針管理的目標(biāo),可以定義一個(gè)公共類,提供引用計(jì)數(shù)的方法,所有對(duì)象都去繼承這個(gè)公共類,這樣就可以實(shí)現(xiàn)所有對(duì)象都可以用引用計(jì)數(shù)來(lái)管理的目標(biāo),在Android中,這個(gè)公共類就是RefBase,同時(shí)還有一個(gè)簡(jiǎn)單版本LightRefBase。RefBase作為公共基類提供了引用計(jì)數(shù)的方法,但是并不去維護(hù)引用計(jì)數(shù)的值,而是由兩個(gè)智能指針來(lái)進(jìn)行管理:sp(Strong Pointer)和wp(Weak
2、0;Pointer),代表強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)。 一、輕量級(jí)引用計(jì)數(shù)的實(shí)現(xiàn):LightRefBaseLightRefBase的實(shí)現(xiàn)很簡(jiǎn)單,只是內(nèi)部保存了一個(gè)變量用于保存對(duì)象被引用的次數(shù),并提供了兩個(gè)函數(shù)用于增加或減少引用計(jì)數(shù)。template <class T>class LightRefBasepublic: inline LightRefBase() : mCount(0) inline void incStrong(const void* id) const android_atomic_inc(&mCount); inline void decStron
3、g(const void* id) const if (android_atomic_dec(&mCount) = 1) delete static_cast<const T*>(this); /! DEBUGGING ONLY: Get current strong ref count. inline int32_t getStrongCount() const return mCount; typedef LightRefBase<T> basetype;protected: inline LightRefBase() private: mutable vo
4、latile int32_t mCount;二、sp(Strong Pointer)LightRefBase僅僅提供了引用計(jì)數(shù)的方法,具體引用數(shù)應(yīng)該怎么管理,就要通過(guò)智能指針類來(lái)管理了,每當(dāng)有一個(gè)智能指針指向?qū)ο髸r(shí),對(duì)象的引用計(jì)數(shù)要加1,當(dāng)一個(gè)智能指針取消指向?qū)ο髸r(shí),對(duì)象的引用計(jì)數(shù)要減1,在C中,當(dāng)一個(gè)對(duì)象生成和銷毀時(shí)會(huì)自動(dòng)調(diào)用(拷貝)構(gòu)造函數(shù)和析構(gòu)函數(shù),所以,對(duì)對(duì)象引用數(shù)的管理就可以放到智能指針的(拷貝)構(gòu)造函數(shù)和析構(gòu)函數(shù)中。Android提供了一個(gè)智能指針可以配合LightRefBase使用:sp,sp的定義如下:template <typename T>class
5、sppublic: inline sp() : m_ptr(0) sp(T* other); sp(const sp<T>& other); template<typename U> sp(U* other); template<typename U> sp(const sp<U>& other); sp(); / Assignment sp& operator = (T* other); sp& operator = (const sp<T>& other); template<type
6、name U> sp& operator = (const 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; inlin
7、e T* operator-> () const return m_ptr; inline T* get() const return m_ptr; / 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_pt
8、r;代碼比較多,其中Accessors部分代碼重載了*、->操作符使我們使用sp的時(shí)候就像使用真實(shí)的對(duì)象指針一樣,可以直接操作對(duì)象的屬性或方法,COMPARE是宏定義,用于重載關(guān)系操作符,由于對(duì)引用計(jì)數(shù)的控制主要是由(拷貝)構(gòu)造函數(shù)和析構(gòu)函數(shù)控制,所以忽略其他相關(guān)代碼后,sp可以精簡(jiǎn)為如下形式(賦值操作符也省略掉了,構(gòu)造函數(shù)省略相似的兩個(gè)):template <typename T>class sppublic: inline sp() : m_ptr(0) sp(T* other); sp(const sp<T>& other); sp(); priva
9、te: template<typename Y> friend class sp; template<typename Y> friend class wp; void set_pointer(T* ptr); T* m_ptr;默認(rèn)構(gòu)造函數(shù)使智能指針不指向任何對(duì)象,sp(T* other)與sp(const sp<T>& other)的實(shí)現(xiàn)如下:template<typename T>sp<T>:sp(T* other): m_ptr(other) if (other) other->in
10、cStrong(this); template<typename T>sp<T>:sp(const sp<T>& other): m_ptr(other.m_ptr) if (m_ptr) m_ptr->incStrong(this);內(nèi)部變量m_ptr指向?qū)嶋H對(duì)象,并調(diào)用實(shí)際對(duì)象的incStrong函數(shù),T繼承自LightRefBase,所以此處調(diào)用的是LightRefBase的incStrong函數(shù),之后實(shí)際對(duì)象的引用計(jì)數(shù)加1。當(dāng)智能指針?shù)N毀的時(shí)候調(diào)用智能指針的析構(gòu)函數(shù):template<typename T>sp<T&g
11、t;:sp() if (m_ptr) m_ptr->decStrong(this);調(diào)用實(shí)際對(duì)象即LightRefBase的decStrong函數(shù),其實(shí)現(xiàn)如下:inline void decStrong(const void* id) const if (android_atomic_dec(&mCount) = 1) delete static_cast<const T*>(this); android_atomic_dec返回mCount減1之前的值,如果返回1表示這次減過(guò)之后引用計(jì)數(shù)就是0了,就把對(duì)象delete掉。三、RefBaseRefBase提供了更強(qiáng)大的
12、引用計(jì)數(shù)的管理。class RefBasepublic: 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
13、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 voi
14、d* 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
15、 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
16、: 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(); /!
17、Flags for extendObjectLifetime() enum OBJECT_LIFETIME_STRONG = 0x0000, OBJECT_LIFETIME_WEAK = 0x0001, OBJECT_LIFETIME_MASK = 0x0003 ; void extendObjectLifetime(int32_t mode); /! Flags for onIncStrongAttempted() enum FIRST_INC_STRONG = 0x0001 ; virtual void onFirstRef(); virtual void onLastStrongRef(
18、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); weakref_impl* const mRefs;不同于LightRefBa
19、se的是,RefBase內(nèi)部并沒(méi)有使用一個(gè)變量來(lái)維護(hù)引用計(jì)數(shù),而是通過(guò)一個(gè)weakref_impl *類型的成員來(lái)維護(hù)引用計(jì)數(shù),并且同時(shí)提供了強(qiáng)引用計(jì)數(shù)和弱引用計(jì)數(shù)。weakref_impl繼承于RefBase:weakref_type,代碼比較多,不過(guò)大都是調(diào)試代碼,由宏定義分開(kāi),Release是不包含調(diào)試代碼的,去除這些代碼后其定義為:#define INITIAL_STRONG_VALUE (1<<28) class RefBase:weakref_impl : public RefBase:weakref_type public: volatile int32_t
20、 mStrong; volatile int32_t mWeak; RefBase* const mBase; volatile int32_t mFlags; 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 addWeakRef(const void* /*id*/) void re
21、moveWeakRef(const void* /*id*/) void printRefs() const void trackMe(bool, bool) ;weakref_impl中的函數(shù)都是作為調(diào)試用,Release版的實(shí)現(xiàn)都是空的,成員變量分別表示強(qiáng)引用數(shù)、弱引用數(shù)、指向?qū)嶋H對(duì)象的指針與flag,flag可控制實(shí)際對(duì)象的生命周期,取值為0或RefBase中定義的枚舉值。RefBase提供了incStrong與decStrong函數(shù)用于控制強(qiáng)引用計(jì)數(shù)值,其弱引用計(jì)數(shù)值是由weakref_impl控制,強(qiáng)引用計(jì)數(shù)與弱引用數(shù)都保存在weakref_impl *類型的成員變量mRe
22、fs中。RefBase同LightRefBase一樣為對(duì)象提供了引用計(jì)數(shù)的方法,對(duì)引用計(jì)數(shù)的管理同樣要由智能指針控制,由于RefBase同時(shí)實(shí)現(xiàn)了強(qiáng)引用計(jì)數(shù)與弱引用計(jì)數(shù),所以就有兩種類型的智能指針,sp(Strong Pointer)與wp(Weak Pointer)。sp前面已經(jīng)說(shuō)過(guò),其(拷貝)構(gòu)造函數(shù)調(diào)用對(duì)象即RefBase的incStrong函數(shù)。void RefBase:incStrong(const void* id) const weakref_impl* const refs = mRefs; refs->incWeak(id); refs->ad
23、dStrongRef(id); const int32_t c = android_atomic_inc(&refs->mStrong); LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); if (c != INITIAL_STRONG_VALUE) return; android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); refs->mBase->onFirstRef(
24、);addStrong的函數(shù)體為空,incStrong函數(shù)內(nèi)部首先調(diào)用成員變量mRefs的incWeak函數(shù)將弱引用數(shù)加1,然后再將強(qiáng)引用數(shù)加1,由于android_atomic_inc返回變量的舊值,所以如果其不等于INITIAL_STRONG_VALUE就直接返回,則則是第一次由強(qiáng)智能指針(sp)引用,將其減去INITIAL_STRONG_VALUE后變成1,然后調(diào)用對(duì)象的onFirstRef。成員變量mRefs是在對(duì)象的構(gòu)造函數(shù)中初始化的:RefBase:RefBase() : mRefs(new weakref_impl(this)weakrel_impl的incWeak繼承自父類we
25、akrel_type的incWeak:void RefBase:weakref_type:incWeak(const void* id) weakref_impl* const impl = static_cast<weakref_impl*> impl->addWeakRef(id); const int32_t c = android_atomic_inc(&impl->mWeak); LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this);addWe
26、akRef實(shí)現(xiàn)同樣為空,所以只是將弱引用計(jì)數(shù)加1。所以當(dāng)對(duì)象被sp引用后,強(qiáng)引用計(jì)數(shù)與弱引用計(jì)數(shù)會(huì)同時(shí)加1。當(dāng)sp銷毀時(shí)其析構(gòu)函數(shù)調(diào)用對(duì)象即RefBase的decStrong函數(shù):void RefBase:decStrong(const void* id) const weakref_impl* const refs = mRefs; refs->removeStrongRef(id); const int32_t c = android_atomic_dec(&refs->mStrong); if (c = 1) const_cast<RefBase*>(th
27、is)->onLastStrongRef(id); if (refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) delete this; refs->removeWeakRef(id); refs->decWeak(id); decStrong中將強(qiáng)引用數(shù)與弱引用數(shù)同時(shí)減1,如果這是最后一個(gè)強(qiáng)引用的話,會(huì)調(diào)用對(duì)象的onLastStrongRef,并且判斷成員變量mRefs的成員變量mFlags來(lái)決定是否在對(duì)象的強(qiáng)引用數(shù)為0時(shí)釋放對(duì)象。mFlags可以為0或以下兩個(gè)枚舉值:enum OBJECT_
28、LIFETIME_WEAK = 0x0001, OBJECT_LIFETIME_FOREVER = 0x0003;mFlags的值可以通過(guò)extendObjectLifetime函數(shù)改變:void RefBase:extendObjectLifetime(int32_t mode) android_atomic_or(mode, &mRefs->mFlags);OBJECT_LIFETIME_FOREVER包含OBJECT_LIFETIME_WEAK(位運(yùn)算中其二進(jìn)制11包含01),所以當(dāng)refs->mFlags&OBJECT_LIFETIME_WEAK) != O
29、BJECT_LIFETIME_WEAK為true時(shí)表示mFlags為0,實(shí)際對(duì)象的生命周期受強(qiáng)引用數(shù)控制,所以在強(qiáng)引用數(shù)為0時(shí)delete this,否則實(shí)際對(duì)象的生命周期就由弱引用數(shù)控制。再來(lái)看decWeak:void RefBase:weakref_type:decWeak(const void* id) weakref_impl* const impl = static_cast<weakref_impl*>(this); impl->removeWeakRef(id); const int32_t c = android_atomic_dec(&im
30、pl->mWeak); if (c != 1) return; if (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) if (impl->mStrong = INITIAL_STRONG_VALUE) delete impl->mBase; else delete impl; else impl->mBase->onLastWeakRef(id); if (impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETI
31、ME_FOREVER) delete impl->mBase; 將弱引用數(shù)減1,若減1后不為0直接返回,否則判斷(impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK若判斷結(jié)果為true: 實(shí)際對(duì)象生命周期被強(qiáng)引用數(shù)控制,接下來(lái)判斷:mpl->mStrong = INITIAL_STRONG_VALUE1. 如果判斷為true表示對(duì)象只被弱引用引用過(guò),現(xiàn)在弱引用數(shù)為0,直接刪除實(shí)際對(duì)象。2. 如果判斷為false,表示對(duì)象曾經(jīng)被強(qiáng)引用引用過(guò),但現(xiàn)在強(qiáng)引用為變?yōu)?了(因?yàn)樵黾踊驕p小
32、強(qiáng)引用數(shù)時(shí)一定同時(shí)增加或減小弱引用數(shù),所以弱引用數(shù)為0時(shí),強(qiáng)引用數(shù)一定為0),弱引用數(shù)為0了,直接釋放mRefs,而實(shí)際對(duì)象由于受強(qiáng)引用數(shù)控制,已經(jīng)在RefBase:decStrong中被delete了。若判斷結(jié)果為false: 判斷mFlgs是否是OBJECT_LIFETIME_FOREVER,如果是,什么都不作由用戶自己控制對(duì)象的生命周期,否則,實(shí)際對(duì)象的生命周期受弱引用數(shù)控制,現(xiàn)在弱引用數(shù)為0,delete實(shí)際對(duì)象。四、wp(Weak Pointer)定義如下:template <typename T>class wppublic: typ
33、edef typename RefBase:weakref_type weakref_type; inline wp() : m_ptr(0) wp(T* other); wp(const wp<T>& other); wp(const sp<T>& other); template<typename U> wp(U* other); template<typename U> wp(const sp<U>& other); template<typename U> wp(const wp<U&
34、gt;& other); wp(); / Assignment wp& operator = (T* other); wp& operator = (const wp<T>& other); wp& operator = (const sp<T>& other); template<typename U> wp& operator = (U* other); template<typename U> wp& operator = (const wp<U>& oth
35、er); template<typename U> wp& operator = (const sp<U>& other); void set_object_and_refs(T* other, weakref_type* refs); / promotion to sp sp<T> promote() const; / Reset void clear(); / Accessors inline weakref_type* get_refs() const return m_refs; inline T* unsafe_get() cons
36、t return m_ptr; / Operators COMPARE(=) COMPARE(!=) COMPARE(>) COMPARE(<) COMPARE(<=) COMPARE(>=) private: template<typename Y> friend class sp; template<typename Y> friend class wp; T* m_ptr; weakref_type* m_refs;同sp一樣,m_ptr指向?qū)嶋H對(duì)象,但wp還有一個(gè)成員變量m_refs。template<typename T>w
37、p<T>:wp(T* other) : m_ptr(other) if (other) m_refs = other->createWeak(this); template<typename T>wp<T>:wp(const wp<T>& other) : m_ptr(other.m_ptr), m_refs(other.m_refs) if (m_ptr) m_refs->incWeak(this); RefBase:weakref_type* RefBase:createWeak(const void* id) const
38、 mRefs->incWeak(id); return mRefs;可以看到,wp的m_refs就是RefBase即實(shí)際對(duì)象的mRefs。wp析構(gòu)的時(shí)候減少弱引用計(jì)數(shù):template<typename T>wp<T>:wp() if (m_ptr) m_refs->decWeak(this);由于弱指針沒(méi)有重載*與->操作符,所以不能直接操作指向的對(duì)象,雖然有unsafe_get函數(shù),但像名字所示的,不建議使用,直接使用實(shí)際對(duì)象指針的話就沒(méi)必要用智能指針了。因?yàn)槿踔羔槻荒苤苯硬僮鲗?duì)象,所以要想操作對(duì)象的話就要將其轉(zhuǎn)換為強(qiáng)指針,即wp:promote方
39、法:template<typename T>sp<T> wp<T>:promote() const return sp<T>(m_ptr, m_refs); template<typename T>sp<T>:sp(T* p, weakref_type* refs) : m_ptr(p && refs->attemptIncStrong(this) ? p : 0)是否能從弱指針生成一個(gè)強(qiáng)指針關(guān)鍵是看refs->attemptIncStrong,看其定義:bool RefBase:weakref
40、_type:attemptIncStrong(const void* id) incWeak(id); weakref_impl* const impl = static_cast<weakref_impl*>(this); int32_t curCount = impl->mStrong; LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow", this); while (curCount > 0 && curCount != INI
41、TIAL_STRONG_VALUE) if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) = 0) break; curCount = impl->mStrong; if (curCount <= 0 | curCount = INITIAL_STRONG_VALUE) bool allow; if (curCount = INITIAL_STRONG_VALUE) / Attempting to acquire first strong reference. this is allowed
42、 / if the object does NOT have a longer lifetime (meaning the / implementation doesn't need to see this), or if the implementation / allows it to happen. allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK | impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); el
43、se / Attempting to revive the object. this is allowed / if the object DOES have a longer lifetime (so we can safely / call the object with only a weak ref) and the implementation / allows it to happen. allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) = OBJECT_LIFETIME_WEAK && impl->mBas
44、e->onIncStrongAttempted(FIRST_INC_STRONG, id); if (!allow) decWeak(id); return false; curCount = android_atomic_inc(&impl->mStrong); / If the strong reference count has already been incremented by / someone else, the implementor of onIncStrongAttempted() is holding / an unneeded reference.
45、 So call onLastStrongRef() here to remove it. / (No, this is not pretty.) Note that we MUST NOT do this if we / are in fact acquiring the first reference. if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) impl->mBase->onLastStrongRef(id); impl->addWeakRef(id); impl->addS
46、trongRef(id); #if PRINT_REFS LOGD("attemptIncStrong of %p from %p: cnt=%dn", this, id, curCount);#endif if (curCount = INITIAL_STRONG_VALUE) android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong); impl->mBase->onFirstRef(); return true;首先通過(guò)incWeak將弱引用數(shù)加1(被強(qiáng)指針sp引用會(huì)導(dǎo)致強(qiáng)引用數(shù)和弱引用
47、數(shù)同時(shí)加1),然后:int32_t curCount = impl->mStrong;while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) = 0) break; curCount = impl->mStrong;如果之前已經(jīng)有強(qiáng)引用,直接將強(qiáng)引用數(shù)加1,android_atomic_cmpxchg表示如果impl->mStrong的值為curCount
48、,則把impl->mString的值改為curCount+1,此處用while循環(huán)是防止其他線程已經(jīng)增加了強(qiáng)引用數(shù)。接下來(lái):if (curCount <= 0 | curCount = INITIAL_STRONG_VALUE)表示對(duì)象目前沒(méi)有強(qiáng)引用,這就要判斷對(duì)象是否存在了。如果curCount = INITIAL_STRONG_VALUE,表示對(duì)象沒(méi)有被sp引用過(guò)。接下來(lái)判斷:allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK | impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); 表示:如果對(duì)象的生命周期只受強(qiáng)引用控制,對(duì)象一定存在,要
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 廠房租賃協(xié)議合同
- 開(kāi)發(fā)商商鋪?zhàn)赓U合同
- 煙酒的購(gòu)銷合同
- 上饒衛(wèi)生健康職業(yè)學(xué)院《人類的生育與健康》2023-2024學(xué)年第二學(xué)期期末試卷
- 梧州醫(yī)學(xué)高等??茖W(xué)?!掇r(nóng)村小學(xué)復(fù)式教學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 曲靖職業(yè)技術(shù)學(xué)院《文學(xué)翻譯(一)》2023-2024學(xué)年第二學(xué)期期末試卷
- 湖北科技學(xué)院《女子乒乓球(I)》2023-2024學(xué)年第二學(xué)期期末試卷
- 山東協(xié)和學(xué)院《藥理學(xué)理論》2023-2024學(xué)年第二學(xué)期期末試卷
- 內(nèi)蒙古鴻德文理學(xué)院《國(guó)際貿(mào)易實(shí)務(wù)模擬實(shí)驗(yàn)》2023-2024學(xué)年第二學(xué)期期末試卷
- 延安大學(xué)西安創(chuàng)新學(xué)院《素描造型人體訓(xùn)練》2023-2024學(xué)年第二學(xué)期期末試卷
- 職業(yè)衛(wèi)生工程控制技術(shù)課件
- 4.1比的意義 導(dǎo)學(xué)案 2022-2023學(xué)年六年級(jí)數(shù)學(xué)上冊(cè)-人教版(含答案)
- 部編人教版九年級(jí)下冊(cè)初中歷史全冊(cè)同步練習(xí)(作業(yè)設(shè)計(jì))
- 孔子仁學(xué)思想
- 六年級(jí)下冊(cè)綜合實(shí)踐活動(dòng)教案(II)
- 高中英語(yǔ)常用詞匯表(動(dòng)詞、名詞、形容詞和副詞)
- 下肢深靜脈血栓形成靜脈置管溶栓術(shù)后-用藥及出血觀察護(hù)理-PPT
- 16萬(wàn)噸_年液化氣綜合利用裝置廢酸環(huán)保綜合利用項(xiàng)目環(huán)境報(bào)告書
- T∕CAEPI 43-2022 電絮凝法污水處理技術(shù)規(guī)程
- 農(nóng)村商業(yè)銀行合規(guī)風(fēng)險(xiǎn)管理暫行辦法
- 油管、套管等規(guī)格對(duì)照表
評(píng)論
0/150
提交評(píng)論