iOS自動引用計數

2021-09-05 09:11:59 字數 2725 閱讀 9733

引用計數:顧名思義,就是物件當前被引用的計數retaincount。當retaincount為0時,表面當前物件沒有被任何其它物件引用;當retaincount不為0時,則物件任被系統中其它物件所引用,所以此時物件還仍被使用中,記憶體不能被系統所**。只用當retaincount為0時,物件才能被系統所**。

1、自己生成的物件,自己持有。

當我們使用alloc,new,copy,mutablecopy生成物件時,則當前物件自己持有該引用計數。

nsobject* object = [nsobject new];
2、非自己生成的物件,自己也能持有。​

當我們使用非方法一的方式生成的物件時,此時可能通過其它方法建立生成的物件當前物件並不持有,此時若是想物件自己持有物件,則我們可以使用以下兩種方式:

// 方法一

nsmutablearray* array = [nsmutablearray array];

[array retain];

//方法二

nsmutablearray* _strong array = [nsmutablearray array];

3、不再需要自己持有的物件時釋放物件。

這個點既是當物件不被任何其它物件引用時,引用計數retaincount為0時則對物件進行釋放。

4、非自己持有的物件無法釋放。

物件若是不持有該物件,則不能對物件執行release操作,否則物件執行時將會報錯。

1、retain操作

objc_object::rootretain(bool tryretain, bool handleoverflow)

uintptr_t carry;

newisa.bits = addc(newisa.bits, rc_one, 0, &carry); // extra_rc++

if (slowpath(carry))

} while (slowpath(!storeexclusive(&isa.bits, oldisa.bits, newisa.bits)));

if (slowpath(transcribetosidetable))

return (id)this;

}

原理分析:

1、當引用計數不溢位時,則將當前的引用計數extra_rc變數值加1;

2、當引用計數溢位時,也即是當extra_rc變數大於255時,此時將rc_half的值也即是128存入sidetable表中,當前引用計數extra_rc的值(256-128=128)為128,之後若是有物件進行引用則再從128開始執行加1計算;在這裡**中有個注意點,當把rc_half(128)存進去sidetable表時,delta_rc因為左移兩位所以值是512,只是因為sidetable表中低兩位是用於作為標識位使用,所以是要左移兩位為512,其實存放的還是溢位物件一半的值即128!

2、release操作

objc_object::rootrelease(bool performdealloc, bool handleunderflow)

} while (slowpath(!storereleaseexclusive(&isa.bits,

oldisa.bits, newisa.bits)));

return false;

underflow:

newisa = oldisa;

size_t borrowed = sidetable_subextrarc_nolock(rc_half);

if (borrowed > 0) }}

}newisa.deallocating = true;

__sync_synchronize();

if (performdealloc)

return true;

}

原理分析:

1、當物件之前沒存在溢位時,則直接將物件引用計數extra_rc值減1;

2、當物件之前存在溢位時,則sidetable表中則存放著物件之前溢位的值,則將rc_half傳入取出128的值再進行減1操作,而且當在sidetable表中取了128的值後,當然對應sidetable表中的值也要進行減去rc_half的值也即是128的操作;再將物件計數值進行儲存,若儲存過程物件出現問題,則將物件直接銷毀;

3、若物件已經處於正在釋放時,則直接呼叫方法進行釋放;

3、retaincount操作

inline uintptr_t 

objc_object::rootretaincount()

return rc;

}return sidetable_retaincount();

}

原理分析:

獲取物件引用計數retaincount的操作,則是將物件的bits.extra_rc值和在sidetable表中存放的值進行相加得到的,但為什麼還要加1呢,是因為bits.extra_rc存放的引用計數減1後的值,也即是當retaincount等於6時,則extra_rc則為5,這就是要進行加1操作的原因。

以上則是對物件引用計數原理的介紹,生成物件遵循引用計數規則對物件進行合理有效地記憶體管理。

自動引用計數

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

自動引用計數

使用弱引用解決迴圈強引用 如果兩個變數屬性都可以設定為nil,那麼就用弱引用來設定其中乙個屬性來解決迴圈強引用。class person weak var apartment apartment?deinit class apartment deinit var aperson person?per...

IOS之引用計數

概念 建立物件時,將它的引用計數設定為1,每一次必須保持該物件時,就傳送一條retain訊息,使其引用計數加1.不再需要物件時,可以通過傳送release訊息,使物件的引用計數減1。當引用計數為0的時候,系統就會釋放它的記憶體,通過向物件傳送dealloc訊息。通過向物件傳送retaincount訊...