addref和release實現的是一種名為引用計數的記憶體管理技術,這種技術是使元件能夠自己將自己刪除的最簡單同時也是效率最高的方法。com元件將維護乙個稱作是引用計數的數值。當客戶蟲元件取得乙個介面時,此數值增1,當客戶使用完某個介面後,此數值將減1。當此數值為0時,元件即可將自己從記憶體中刪除。
為正確的使用引用計數,需要了解一下三條規則:
(1) 在返回之前呼叫addref。對於哪些返回介面指標的函式,包括queryinte***ce和createinstance,在返回之前用相應的指標呼叫addref。
(2) 使用完介面之後呼叫此介面的release函式。
(3) 在賦值之後呼叫addref。如在將乙個介面賦給另外乙個介面指標時呼叫addref。
生命期巢狀在引用同一介面的指標的生命期內的指標可以不進行引用計數。在函式中,無需對存在於區域性變數的介面指標進行引用計數。因為區域性變數的生命期同函式的生命期是一樣的,因此也將包含在呼叫者的生命期內。但當從某個全域性變數或向某個全域性變數複製乙個指標時,則需要對此指標進行引用計數,因為全域性變數可以從任意函式中的任意地方被釋放。
一般而言,客戶必須為每乙個介面維護乙個單獨的引用計數值。
總結引用計數的幾條具體規則如下:
(1)輸出引數規則。任何在輸出引數中(如queryinte***ce的void** ppv)或作為返回值返回乙個新的介面指標的函式必須對此介面指標呼叫addref。即在返回之前呼叫addref。
(2)輸出引數規則。在輸入引數(c++的按值傳遞的引數或常量)傳入函式的介面指標,無需呼叫addref和release。因為函式的生命期巢狀在呼叫者的生命期內。
(3)輸入-輸出引數規則,即在函式體中可以使用輸入-輸出引數的值,然後可以對這些制進行修改並將其返回給呼叫者,對於具有這種功能的引數傳進來的介面指標,必須在給它賦另外乙個介面指標值之前呼叫其release,並在函式返回之前,對輸入引數中所儲存的介面指標呼叫addref。
(4)區域性變數規則。對於區域性複製的介面指標,由於它們只在函式的生命期內才存在,無需呼叫addref和release。
(5)全域性變數規則。對於儲存在全域性變數中的介面指標,在將其傳遞給另外乙個函式之前,必須呼叫其addref。對於儲存在成員變數中的介面指標,也應按此中方式進行處理。因為類中的任何成員函式都可以改變此中介面指標的狀態。
(6)不能確定時的規則。對於任何不能確定的情形,都應呼叫addref和release。
在決定要對引用計數進行優化時,應給哪些沒有進行引用計數的指標加上相應的注釋,否則,其他程式設計師在修改**時,將可能會增大介面指標的生命期,從而使引用計數的優化遭到破壞。
自動引用計數
每當你產生乙個物件,arc分配一大塊控制項去儲存這個物件。除此之外,當乙個物件是不在需要,arc 將會收回這個例項物件所佔的空間。如果乙個物件的空間被釋放掉,但是你任然通過物件的引用呼叫方法或者屬性,你的程式將要崩潰。為了不讓物件被釋放掉 arc將會追蹤有多少屬性 常量 變數正在引用這個物件。只要有...
引用計數 copy on write
拷貝通常分為值拷貝也叫淺拷貝和深拷貝,當拷貝方式為淺拷貝時就會有以下兩個問題 1 當需要調析構函式時,會出現同一塊空間被析構兩次的情況 2 如果是對指標的淺拷貝,會讓兩個指標同時管理同一塊空間,當乙個指針對這塊空間進行修改時,會影響到另外乙個指標。通過引用計數加寫時拷貝可以有效地解決這些問題。引用計...
自動引用計數
使用弱引用解決迴圈強引用 如果兩個變數屬性都可以設定為nil,那麼就用弱引用來設定其中乙個屬性來解決迴圈強引用。class person weak var apartment apartment?deinit class apartment deinit var aperson person?per...