arc有效時所有型別都必須加上所有權修飾符。所有權修飾符一共有四種:
__strong 修飾符
__strong修飾符是預設修飾符,表示物件的「強引用」,強引用物件在超出其作用域時將會被廢棄,引用的物件釋放。
id __strong obj1 = [[nsobject alloc]init];
id __strong obj2 = obj1;
obj1 = nil;
/*** obj1 = nil, obj2 != nil**/
uiview *view1 = [[uiview alloc]init];
uiview *view2 = view1;
view1.alpha = 0.4;
view2.alpha = 0.5;
/*** view1.alpha = 0.5, view2.alpha = 0.5
**/
通過上面這段**希望大家能明白記憶體管理的思考方式。
__strong修飾符能夠對同一段記憶體進行持有,並共同管理。
obj1釋放時引用計數-1,這個時候只有obj2指向記憶體,因為是強引用,所以這個時候引用計數仍為1,所以記憶體並沒有釋放。view1和view2共同管理同一段記憶體,所以當view2修改以後,view1的值也會進行變化,因為指向同一段記憶體。
__weak 修飾符
然而strong修飾符並不能解決所有問題,當兩個物件相互強引用對方的成員變數的時候,就會發生迴圈引用,迴圈引用容易發生記憶體洩漏。所謂記憶體洩漏就是應當廢棄的物件在超出其生命週期後繼續存在。那麼在這個時候就引入了weak修飾符,「弱引用」。
因為帶weak修飾符的變數(即弱引用)不持有物件,所以在超出其作用域時,物件就會釋放,所以因為強引用而造成的迴圈引用,將其中的成員變數改為弱引用,就不會發生相同情況。
__weak修飾符還有另外乙個優點。在持有某若引用時,若該物件被廢棄,則此弱引用將自動失效且處於nil被賦值狀態(空弱引用)。如以下**所示。
nsobject __strong *obj1 = [[nsobject alloc]init];
nsobject __weak *obj2 = obj1;
obj1 = nil;
/*** obj1 = nil, obj2 = nil;
**/
通過使用weak修飾符可避免迴圈引用。通過檢查附有weak修飾符的變數是否為nil,可以判斷被賦值物件是否已廢棄。
遺憾的是,weak修飾符只能用於ios5以上及os x lion以上版本的應用程式。在ios4以及os x snow leopard的應用程式中可使用unsafe unretained修飾符來代替。
__unsafe unretained 修飾符
unsafe unretained與weak修飾符一樣不會增加引用計數,自己生成的物件不能繼續為自己所有,所以會立即釋放。
那麼unsafe unretained修飾符與weak修飾符有什麼區別呢?
比如在ios4以及os x snow leopard的應用程式中,必須使用unsafe unretained修飾符來替代weak修飾符。賦值給附有__unsafe unretained修飾符變數的物件在通過該變數使用時,如果沒有確保其存在,那麼應用就會崩潰。__autoreleasing 修飾符
arc有效時不能使用autorelease方法,同時不能使用nsautoreleasepool類。但是,事實上arc有效時auto lease功能也是起作用的。
以下兩段**是相同的:
/*arc無效*/
nsautoreleasepool *pool = [[ns nsautoreleasepool alloc] init];
id obj = [[nsobject alloc] init];
[obj autorelease];
[pool drain];
/*arc有效*/
@autoreleasepool
/*** obj已釋放
**/
指定「@autoreleasepool塊」來替代「nsautoreleasepool類物件生成、持有以及廢棄」這一範圍。
另外,arc有效時,要通過將物件賦值給附加了autoreleasing修飾符的變數來替代呼叫autorelease方法。物件賦值給附有autoreleasing修飾符的變數等價於在arc有效時呼叫物件的autorelease方法,即物件被註冊到autoreleasepool。
也就是可以說arc有效時,用@aotureleasepool塊替代nsautoreleasepool類,用附有__autoreleasing修飾符的變數替代autorelease方法。
因為autoreleasepool範圍以塊級源**表示,提高了程式的可讀性,所以今後在arc無效時也推薦使用@autoreleaseepool塊。上面講解了四種修飾符,在arc有效的情況下,必須遵守一定的規則。下面就是具體的arc規則:另外,無論arc是否有效,除錯用的非公開函式_objc_autoreleasepoolprint()都可使用。
_objc_rootretaincount(obj)
利用這一函式可有效的幫助我們除錯註冊到autoreleasepool上的物件。
最後我們來看一下arc中自動引用計數的數值究竟是多少
我們來看這段**:
//retain count = 0;
和我們預期的一樣,strong修飾符使引用技術+1,而weak修飾符,並不會使修飾符+1,早超出obj的作用域以後,引用技術-1,同時釋放。我們再來看一下用__autoreleasing修飾符向autoreleasepool註冊會怎麼樣:
@autoreleasepool
//retain count = 0;
__autoreleasing修飾符,使引用計數+1,而在超出autoreleasepool以後則清空並釋放。最後再來看一下在autoreleasepool中使用__weak修飾符是什麼樣的:
@autoreleasepool
在autoreleasepool中即使不使用autoreleasing修飾符,而用__weak修飾符替代,同樣將obj物件註冊到了autoreleasepool中。
iOS記憶體管理 ARC
arc是在編譯的時候插入 來確信讓物件能夠按需要來存在。arc同樣是以引用計數為基礎。你可以選擇在以檔案或者專案為單位不使用arc。但是建議盡量最好使用arc,首先,編譯器為你做記憶體管理往往比你自己要更優秀,其次,arc導致的效率損失在ui面前基本可以忽略不計。arc有以下強制規則 1.你不能顯示...
ARC下的記憶體管理
本文討論一下arc automatic referencing count 下的記憶體管理問題 例項變數是類的私有成員變數,無法被外部訪問,並且子類無法繼承。屬性以 property修飾,是封裝了getter setter方法的 成員變數 可以被外部訪問和被繼承。宣告屬性後,系統會生成乙個名為 pr...
iOS基礎之記憶體管理 一 ARC下的記憶體洩漏
arc automatic reference counting,自動引用計數 是指在記憶體管理中採取自動計數的技術。在llvm編譯器中設定arc為有效狀態,就無需再次鍵入retain或者release 蘋果官方說明換言之,滿足下面的條件就無需手動輸入retain release了 使用xcode4...