block
的介紹==
ios
中的內存空間分級==ios
BSS
區(BSS
是英文Block Started by Symbol
的簡稱。BSS
段屬於靜態內存分配。BSS
節不包含任何數據,只是簡單的維護開始和結束的地址,以便內存區能在運行時被有效地清零。BSS
節在應用程序的二進制映象文件中並不存在。)。數據區存放已經初始化好的靜態變量以及全局變量,而BSS區則存放尚未初始化好的靜態變量以及全局變量,由系統負責釋放以及分配。==
block
的分級==算法
Block
:__NSGlobalBlock__
;
block
時,若是這個block
沒有捕獲外部的變量,那麼這個block
就位於全局區,此時對NSGlobalBlock
的retain、copy、release
操做都無效。Block
:__NSStackBlock__
;
block
,爲何呢?由於在ARC環境下,當咱們聲明而且定義了一個block
,而且沒有爲Block
添加額外的修飾符(默認是__strong
修飾符),若是該Block
捕獲了外部的變量,實質上是有一個從__NSStackBlock__
轉變到__NSMallocBlock__
的過程,只不過是系統幫咱們完成了copy
操做,將棧區的block
遷移到堆區,延長了Block
的生命週期。對於棧區block
而言,棧block
在當函數退出的時候,該空間就會被回收。何時在ARC
的環境下出現__NSStackBlock__
呢?若是咱們在聲明一個block的時候,使用了__weak
或者__unsafe__unretained
的修飾符,那麼系統就不會爲咱們作copy
的操做,不會將其遷移到堆區。Block
:__NSMallocBlock__
;
咱們須要手動調用copy
方法才能夠將block
遷移到堆區,而在ARC環境下,__strong
修飾的(默認)block
只要捕獲了外部變量就會位於堆區,NSMallocBlock
支持retain、release
,會對其引用計數+1或 -1。編程
==
__block
修飾符==緩存
block
的特殊性,block
也屬於「函數」的範疇,變量進入block
,實際就是已經改變了做用域。在幾個做用域之間進行切換時,若是不加上這樣的限制,變量的可維護性將大大下降。又好比我想在block
內聲明瞭一個與外部同名的變量,此時是容許呢仍是不容許呢?只有加上了這樣的限制,這樣的情景才能實現。因而棧區變成了紅燈區,堆區變成了綠燈區。block
並不能做出修改。咱們要改變外部變量的內存地址,也就是使用__block
修飾符將外部變量在棧中指針的內存地址,遷移到堆區中來。__block
修飾符的根本操做就是改變外部變量的內存地址,並非簡單地使得寫操做生效。__block
做爲修飾符。將block
捕獲的外部變量使用static
修飾或者將外部變量聲明爲全局變量,那麼block
是能夠直接修改該外部變量的,由於全局變量或靜態變量在內存中的地址是固定的(存放於靜態區),Block
在讀取該變量值的時候是直接從其所在內存讀出,獲取到的是最新值,而不是在定義時copy
的常量。某些圖方便直接用copy
修飾生命block
。直接拿到一個堆區block
。裏面捕獲變量的過程當中就不須要修飾符來讓OS
幫忙拷貝直接可使用了。可是原理必定要清晰,一個失控的機制遠比可控的機制恐怖的多。這裏須要警醒。多線程
==循環引用的原理==閉包
OS
的斷定機制會認爲這個空間仍在使用,因此相關聯的三方資源一個都不會釋放;__weak
的弱引用替換掉__strong
的時候會打破閉環釋放三方資源。可是隨之到來的是unsafe
。這是須要注意的地方;函數
==
block
到底是個什麼東西==線程
block
算是一個另類的函數。是將代碼段閉包抽象爲一種對象調用的手段。==多線程下的
block
==指針