引用計數 nRefs 說明和使用

2021-06-01 20:59:04 字數 2283 閱讀 1196

brew介面包含了物件導向的概念,所有介面都以ibase為基類,而ibase定義了最基本的兩個方法:ibase_addrefibase_release

這兩個方法都和乙個變數緊密關聯,這就是 nrefs - 引用計數。每個介面(且稱之為aaa)的aaa_addref()的實現就是將引用計數加一:

++me->nrefs

而每個介面物件的釋放函式設計都如下面模式:

uint32 aaa_release(void *po)

if (me->base.nrefs == 1)

aaa_dtor(me); // 資源釋放呼叫    }

return --me->nrefs;

可見只有當引用計數降到1時,才真正釋放資源。

很少情況下會顯式地呼叫ibase_addref(),這意味著在釋放時要呼叫aaa_release()多次才能真正釋放資源。

引用計數的意義在於,可能有多個其它關聯物件同時需要使用此物件的資源,關聯物件與此物件的關係可能是包含關係,有可能是繼承關係,引用計數反映了這些關聯物件的個數,只有所有關聯物件都釋放了,此物件資源才真正被釋放。

乙個物件的引用計數都是隱含地增加的,即物件的aaa_addref()都是被隱含地透明地呼叫,呼叫發生在與關聯物件相互作用之時,buiw設計中經常在下面四種情況下隱含地呼叫aaa_addref()。

(一). 容器(container)獲取其widget時

以根容器為例,建立根容器並獲取其widget的**如下:

ishell_createinstance(pme->pishell, aeeclsid_rootcontainer, (void**)&pme->picroot);

irootcontainer_queryinte***ce(pme->picroot, aeeiid_widget, (void**)&pme->piwroot);

其中pme->piwroot與pme->picroot的關係是組合關係,即pme->picroot包含pme->piwroot,pme->picroot建立時,其中的widget物件的引用計數已經是1,當irootcontainer_queryinte***ce()將widget取出單獨使用時,widget的引用計數加一,即為2,所以在釋放資源時,需要呼叫如下:

releaseif(pme->picroot);

releaseif(pme->piwroot);

前一句釋放根容器資源時也同時試圖釋放其widget資源,但其效果僅僅是將widget引用計數減一,到第二句才真正釋放widget資源。

(二). 向容器(container)插入widget時容器往往管理多個widget,管理關係的建立需要首先將widget插入到容器中:

(void)ixycontainer_insert(pme->pxycontainer, piwstatichello, widget_znormal, &dwpos);

// 隨後在本函式中釋放臨時變數 piwstatichello

releaseif(piwstatichello);

實際上,呼叫ixycontainer_insert()時,piwstatichello的引用計數增一,隨後的釋放(releaseif(piwstatichello))並沒有將piwstatichello指向的物件資源釋放掉,僅僅是引用計數減一,而piwstatichello指向的物件資源釋被pme->pxycontainer管理且跟隨它被釋放。

(三). 向修飾器(container)設定被修飾widget時

修飾器pid修飾widget ppiw時,需要呼叫

idecorator_setwidget(pid, *ppiw);

releaseif(*ppiw);

ppiw在呼叫idecorator_setwidget()之前,引用計數可能為1,呼叫idecorator_setwidget()則增一,變為2,releaseif(*ppiw)後,引用計數減為1,但是物件資源沒有釋放,而是被修飾器管理並跟隨它被釋放。

(四). widget設定model時

widget與model各自建立,然後使用下面語句將model設定到widget

iwidget_setmodel(piw, ivectormodel_to_imodel(pivm));

設定完成意味著model被widget管理,model pivm建立時引用計數為1,呼叫iwidget_setmodel()後引用計數為2,那麼如想完全釋放model物件資源,需要呼叫下面兩個釋放操作:

releaseif(pivm);

releaseif(piw);

缺少任意乙個,都不會將pivm引用計數降為0,從而不會真正釋放pivm資源,造成記憶體洩漏。

引用計數和AddRef Release

addref和release實現的是一種名為引用計數的記憶體管理技術,這種技術是使元件能夠自己將自己刪除的最簡單同時也是效率最高的方法。com元件將維護乙個稱作是引用計數的數值。當客戶蟲元件取得乙個介面時,此數值增1,當客戶使用完某個介面後,此數值將減1。當此數值為0時,元件即可將自己從記憶體中刪除...

自動引用計數

每當你產生乙個物件,arc分配一大塊控制項去儲存這個物件。除此之外,當乙個物件是不在需要,arc 將會收回這個例項物件所佔的空間。如果乙個物件的空間被釋放掉,但是你任然通過物件的引用呼叫方法或者屬性,你的程式將要崩潰。為了不讓物件被釋放掉 arc將會追蹤有多少屬性 常量 變數正在引用這個物件。只要有...

引用計數 copy on write

拷貝通常分為值拷貝也叫淺拷貝和深拷貝,當拷貝方式為淺拷貝時就會有以下兩個問題 1 當需要調析構函式時,會出現同一塊空間被析構兩次的情況 2 如果是對指標的淺拷貝,會讓兩個指標同時管理同一塊空間,當乙個指針對這塊空間進行修改時,會影響到另外乙個指標。通過引用計數加寫時拷貝可以有效地解決這些問題。引用計...