ARC Objective c的記憶體管理

2021-07-05 11:55:03 字數 4215 閱讀 5088

什麼是arc:

arc是ios 5推出的新功能,全稱叫 arc(automatic reference counting)。簡單地說,就是**中自動加入了retain/release,原先需要手動新增的用來處理記憶體管理的引用計數的**可以自動地由編譯器完成了。

該機能在 ios 5/ mac os x 10.7 開始匯入,利用 xcode4.2 可以使用該機能。簡單地理解arc,就是通過指定的語法,讓編譯器(llvm 3.0)在編譯**時,自動生成例項的引用計數管理部分**。有一點,arc並不是gc,它只是一種**靜態分析(static analyzer)工具。

變化:

通過一小段**,我們看看使用arc前後的變化點。

@inte***ce nonarcobject : nsobject   

-(id)initwithname:(nsstring *)name;

@end

@implementation nonarcobject

-(id)initwithname:(nsstring *)newname

return self;

}

-(void)dealloc

@end

@inte***ce arcobject : nsobject   

-(id)initwithname:(nsstring *)name;

@end

@implementation arcobject

-(id)initwithname:(nsstring *)newname

return self;

} @end

我們之前使用objective-c中記憶體管理規則時,往往採用下面的準則

而使用arc後,我們可以不需要這樣做了,甚至連最基礎的release都不需要了。

使用arc有什麼好處呢?

1、看到上面的例子,大家就知道了,以後寫objective-c的**變得簡單多了,因為我們不需要擔心煩人的記憶體管理,擔心記憶體洩露了

2、**的總量變少了,看上去清爽了不少,也節省了勞動力

3、**高速化,由於使用編譯器管理引用計數,減少了低效**的可能性

不好的地方:

關於第二點,由於 xcode4.2 中預設arc就是 on 的狀態,所以編譯舊**的時候往往有"automatic reference counting issue"的錯誤資訊。

這個時候,可以將專案編譯設定中的「objectice-c auto reference counteting」設為no。如下所示。

如果只想對某個.m檔案不適應arc,可以只針對該類檔案加上 -fno-objc-arc 編譯flags,如下圖。

arc基本規則:

由於arc並不是gc,並需要一些規則讓編譯器支援**插入,所以必須清楚清楚了這些規則後,才能寫出健壯的**。

objectivec物件:

objectivec中的物件,有強參照(strong reference)和弱參照(weak reference)之分,當需要保持其他物件的時候,需要retain以確保物件引用計數加1。物件的持有者(owner)只要存在,那麼該物件的強參照就一直存在。

物件處理的基本規則是

firstname作為」natsu」字串物件的最初持有者,是該nsstring型別物件的strong reference。

(s2)

這裡將firstname代入到aname中,即aname也成為了@」natsu」字串物件的持有者,對於該物件,aname也是strong reference。

(s3)

這裡,改變firstname的內容。生成新的字串物件」maki」。這時候firstname成為」maki」的持有者,而@」natsu」的持有者只有aname。每個字串物件都有各自的持有者,所以它們都在記憶體中都存在。

(s4)

追加新的變數othername, 它將成為@」maki」物件的另乙個持有者。即nsstring型別物件的strong reference。

(s5)

將othername代入到aname,這時,aname將成為@」maki」字串物件的持有者。而物件@」natsu」已經沒有持有者了,該物件將被破棄

弱參照:

與強參照方式同樣,firstname作為字串物件@」natsu」的持有者存在。即是該nsstring型別物件的strong reference。

(w2)

使用關鍵字__weak,宣告弱參照weakname變數,將firstname代入。這時weakname雖然參照@」natsu」,但仍是weak reference。即weakname雖然能看到@」natsu」,但不是其持有者。

(w3)

firstname指向了新的物件@」maki」,成為其持有者,而物件@」natsu」因為沒有了持有者,即被破棄。同時weakname變數將被自動代入nil。

引用關鍵字:

arc中關於物件的引用參照,主要有下面幾關鍵字。使用strong, weak, autoreleasing限定的變數會被隱式初始化為nil。

1、__strong

變數宣告預設都帶有__strong關鍵字,如果變數什麼關鍵字都不寫,那麼預設就是強參照。

2、__weak

上面已經看到了,這是弱參照的關鍵字。該概念是新特性,從 ios 5/ mac os x 10.7 開始匯入。由於該型別不影響物件的生命週期,所以如果物件之前就沒有持有者,那麼會出現剛建立就被破棄的問題,比如下面的**。

nsstring __weak *string = [[nsstring alloc] initwithformat:@"first name: %@", [self firstname]];  

nslog(@"string: %@", string); //此時 string為空

如果編譯設定os版本 deployment target 設定為這比這低的版本,那麼編譯時將報錯(the current deployment target does not support automated __weak references),這個時候,我們可以使用下面的 __unsafe_unretained。

弱參照還有乙個特徵,即當引數物件失去所有者之後,變數會被自動付上nil (zeroing)。

3、__unsafe_unretained

該關鍵字與__weak一樣,也是弱參照,與__weak的區別只是是否執行nil賦值(zeroing)。但是這樣,需要注意變數所指的物件已經被破棄了,位址還還存在,但記憶體中物件已經沒有了。如果還是訪問該物件,將引起「bad_access」錯誤。

4、__autoreleasing

該關鍵字使對像延遲釋放。比如你想傳乙個未初始化的對像引用到乙個方法當中,在此方法中例項化此對像,那麼這種情況可以使用__autoreleasing。他被經常用於函式有值引數返回時的處理,比如下面的例子。

- (void) generateerrorinvariable:(__autoreleasing nserror **)paramerror   

....

又如函式的返回值是在函式中申請的,那麼希望釋放是在呼叫端時,往往有下面的**。

-(nsstring *)stringtest     

// 使用arc

-(nsstring *)stringtest

即當方法的引數是id*,且希望方法返回時物件被autoreleased,那麼使用該關鍵字。

總結:

今天,我們看到了基本的arc使用規則

內點法python 內點法

文字理解 內點法屬於約束優化演算法。約束優化演算法的基本思想是 通過引入效用函式的方法將約束優化問題轉換成無約束問題,再利用優化迭代過程不斷地更新效用函式,以使得演算法收斂。內點法 罰函式法的一種 的主要思想是 在可行域的邊界築起一道很高的 圍牆 當迭代點靠近邊界時,目標函式徒然增大,以示懲罰,阻止...

Hibernate框架的內連線和迫切內連線

public class hqltest catch exception e finally test public void fun2 內連線,以陣列方式進行儲存 string hql from customer c inner join c.setperson query query sessi...

AngularJS內的服務

通過之前講解的一些angularjs裡面的一些功能j 今天就來說下我用angulaerjs裡面的服務的一些感觸和運用。angularjs中你可以自己建立自己的服務,也可以使用angularjs裡面的內建服務。在angularjs中,服務是乙個函式或物件,可在你的angularjs 應用中使用。有個 ...