block内存篇
本文目的:對Block內(nèi)存問題更加了解 概念理解:一種數(shù)據(jù)類型或比較特殊的對象,相當(dāng)于一個指向函數(shù)的指針,該指針指向一段封裝代碼,調(diào)用block塊代碼好比調(diào)用該指針指向的函數(shù)代碼 block分類:
NSGlobalBlock:未引用外部任何變量即為NSGlobalBlock NSStackBlock:引用外部變量,且只有一次執(zhí)行,block返回后棧區(qū)將釋放該block
NSMallocBlock:當(dāng)需要多次執(zhí)行時,就會把該block從棧中copy到堆中,以便多次執(zhí)行 block-arc/mrc內(nèi)存問題: mrc下引用外部變量,則block是在棧區(qū);arc下block默認(rèn)生成于棧區(qū),然后自動copy至堆區(qū)。
mrc環(huán)境:
1.當(dāng)打印myBlock時發(fā)現(xiàn)mrc下對外部變量引用是在棧區(qū),并沒有進(jìn)行copy至堆區(qū)
2.myBlock內(nèi)部對外部變量stopName進(jìn)行引用,執(zhí)行block的時候內(nèi)存計(jì)數(shù)器仍為1,證明retain失效,從而證明棧區(qū)無法release、retain,由系統(tǒng)自動分配和釋放內(nèi)存;
3.對myBlock進(jìn)行copy,發(fā)現(xiàn)yourBlock是在堆區(qū),stopName內(nèi)存計(jì)數(shù)器+1
arc環(huán)境:
執(zhí)行myBlock,發(fā)現(xiàn)是在堆區(qū),證明arc環(huán)境下回自動將block從棧區(qū)copy至堆區(qū)
- NSGlobalBlock:位于全局靜態(tài)區(qū)。
- NSStackBlock:位于棧區(qū),函數(shù)返回時被銷毀
- NSMallocBlock:位于堆區(qū),當(dāng)引用計(jì)數(shù)為0時被銷毀,由NSStackBlock從棧區(qū)copy到堆區(qū)
?
?
?
?
?
?
?
?
?
?
棧區(qū)(stack):由系統(tǒng)自動分配,一般存放函數(shù)參數(shù)值、局部變量的值等。由編譯器自動創(chuàng)建與釋放。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧,即后進(jìn)先出、先進(jìn)后出的原則
堆區(qū)(heap):一般由程序員申請并指明大小,最終也由程序員釋放。如果程序員不釋放,程序結(jié)束時可能會由OS回收。
全局區(qū)/靜態(tài)區(qū):顧名思義,全局變量和靜態(tài)變量存儲在這個區(qū)域。只不過初始化的全局變量和靜態(tài)變量存儲在一塊,未初始化的全局變量和靜態(tài)變量存儲在一塊。程序結(jié)束后由系統(tǒng)釋放。
文字常量區(qū):這個區(qū)域主要存儲字符串常量。程序結(jié)束后由系統(tǒng)釋放。
程序代碼區(qū):這個區(qū)域主要存放函數(shù)體的二進(jìn)制代碼
例子: int a = 0; // 全局初始化區(qū) char *p1; // 全局未初始化區(qū) main {int b; // 棧char s[] = "abc"; // 棧char *p2; // 棧char *p3 = "123456"; // 123456\0在常量區(qū),p3在棧上static int c =0; // 全局靜態(tài)初始化區(qū)p1 = (char *)malloc(10);p2 = (char *)malloc(20); // 分配得來的10和20字節(jié)的區(qū)域就在堆區(qū)strcpy(p1, "123456"); // 123456\0在常量區(qū),這個函數(shù)的作用是將"123456" 這串字符串復(fù)制一份放在p1申請的10個字節(jié)的堆區(qū)域中。// p3指向的"123456"與這里的"123456"可能會被編譯器優(yōu)化成一個地址。 } block區(qū)分:NSGlobalBlock:未引用外部任何變量即為NSGlobalBlock NSStackBlock:引用外部變量,且只有一次執(zhí)行,block返回后棧區(qū)將釋放該block
NSMallocBlock:當(dāng)需要多次執(zhí)行時,就會把該block從棧中copy到堆中,以便多次執(zhí)行 block-arc/mrc內(nèi)存問題: mrc下引用外部變量,則block是在棧區(qū);arc下block默認(rèn)生成于棧區(qū),然后自動copy至堆區(qū)。
mrc環(huán)境:
1.當(dāng)打印myBlock時發(fā)現(xiàn)mrc下對外部變量引用是在棧區(qū),并沒有進(jìn)行copy至堆區(qū)
2.myBlock內(nèi)部對外部變量stopName進(jìn)行引用,執(zhí)行block的時候內(nèi)存計(jì)數(shù)器仍為1,證明retain失效,從而證明棧區(qū)無法release、retain,由系統(tǒng)自動分配和釋放內(nèi)存;
3.對myBlock進(jìn)行copy,發(fā)現(xiàn)yourBlock是在堆區(qū),stopName內(nèi)存計(jì)數(shù)器+1
arc環(huán)境:
執(zhí)行myBlock,發(fā)現(xiàn)是在堆區(qū),證明arc環(huán)境下回自動將block從棧區(qū)copy至堆區(qū)
?代碼分享:內(nèi)容包括定義、使用、循環(huán)引用、內(nèi)存覆蓋等問題例子
百度云:http://pan.baidu.com/s/1c1Y21hA
轉(zhuǎn)載于:https://www.cnblogs.com/Eazy/p/5401518.html
總結(jié)
- 上一篇: 【 D3.js 入门系列 --- 2 】
- 下一篇: vb6中word编程总结