ARC中block块作为属性的使用笔记
ARC中block塊作為屬性的使用筆記
block較難理解,根據在內存中的分布情況就分為3種類型,根據使用的情形又分為很多很多種。雖然用起來容易,但使用不當會造成內存泄露,雖然都是這么說,但你真的研究過為什么會泄露嗎?為什么有些時候外部變量進入block的時候會導致引用計數+1呢?
?
本人做過MRC以及ARC的開發,但大勢所趨,ARC將是以后開發的主要模式,即使有MRC也是ARC混編MRC的代碼,所以,本文的block的一些使用上的心得都基于ARC的,已經不考慮MRC的了,請看官注意,MRC與ARC的block是有著很多很多區別的。
?
注意,以下心得是我自己長時間收集資料以及自己驗證所的出來的一些技巧與結論,不代表它的正確性,這僅僅是筆記,取舍由你決定,最好自己驗證一下。
首先建立出如下形式的工程,CV1 push 到CV2的這種形式。
它們的強引用關系如下:
以下是CV2的代碼,注意,要將block定義成copy屬性。
block被copy了有著什么現象發生呢?引用一段原文。
http://stackoverflow.com/questions/16149653/what-is-the-role-of-the-copy-in-the-arc
Blocks are similar to other objects for memory management, but not the same. When a block which accesses local variables is created, it is created on the stack. This means that it is only valid as long as its scope exists. To save this block for later, you must copy it, which copies it to the heap.
Blocks與其他對象的內存管理相似,但又有著不同。當一個block(block當中有著外部變量進入)被創建了,它是在堆區中的。那意味著,當block中的代碼執行完畢之后,這段代碼就再也不合法了,會被清除掉。為了讓這個block存活時間更久。你必須copy,將它拷貝到棧區。
1. CV1 push 到CV2,CV2在棧區里面,CV2 pop 掉后整個控制器都被釋放。
2. 作為屬性的block被copy之后會出現在CV2棧區里面,為什么在棧區里面,很簡單,它要隨著CV2的生命周期一致,CV2 pop 掉后這個block也會跟著一起消失的。
他們的強引用關系如下圖所示:
以下情形叫做有外部變量進入block的情形,其中的self.name就是控制器CV2的一個屬性,對于block來講屬于外部變量。
這里有一個問題,對于進入到block里面的外部變量,為什么會被block強引用呢?
我們可以這么想,block塊中的代碼并不是馬上就會執行的,需要你手動調用才行,如上例中的self.oneBlock(@“YouXianMing”);有時候,這個方法都執行結束了,這個block還沒有執行,如果block中的對象沒有被block強引用,很有可能那個變量已經消失了卻還調用了block,直接后果就是崩潰。為了保證block至少能用上一次,它必須強引用進入到里面的外部變量。
所以上圖中的強引用關系圖如下所示:
如果CV2 pop 了,其釋放過程是這樣子的:
CV2被CV1強引用消失,CV2就會挨個檢查強引用,如果沒有發現自己被什么強引用,就會把所有的內容清除掉,就是上圖中的oneBlock以及name。
最后,之后輪到oneBlock了,它也會解除name的強引用關系:
至此,都是很完美的,沒有內存泄露什么的。
我們把代碼修改成如下的形式,我們在block中執行一個方法,讓控制器執行一個方法,即[self ......];
它們的強引用關系圖如下,注意下圖中的藍色的線條,因為外部變量self(CV2自身)傳了進來,只出現的self也算傳進來了哦。
這個時候,你如果將 CV2 pop掉。它們的關系圖如下所示:
這個時候,CV2會檢測自己有沒有被強引用,結果發現被一個對象oneBlock強引用了,那么它自身就不會被釋放掉,整個CV2都泄露了呢,泄露的原因就是循環引用。
這時候,你再從CV1 push 出CV2,以下是關系圖:
再次pop又會泄露一個CV2。每次的push與pop都會導致一個新的CV2整體被泄露哦。
?
這還只是作為屬性的block。其他的還沒講呢。作為屬性的block是最容易出現循環引用事件的。block的知識都比較隱晦,你以為你懂了,其實你沒懂。需要抱著一顆不浮躁的心,慢慢的分析它的特性,寫代碼驗證自己的想法,然后才會使用得得心應手。
?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的ARC中block块作为属性的使用笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 模板插件aTpl.js新增功能
- 下一篇: Android Open Accesso