iOS開發入門 ☞ OC語言·筆記八,iosoc
block(代碼塊)
1.1 什麼是block
- block是iOS中一種比較特殊的資料類型。(可以定義變數、做形參或傳回值)
- block是蘋果官方精選使用的資料類型,應用情境比較廣泛
在多線程和網路也使用得相當頻繁,一般都是作為回調使用!
- block的作用
- 和函數一樣,用來儲存某一段代碼,可以在恰當的時間再取出來調用
- block功能類似於函數(方法),比函數更強大。
- block是一種資料類型,可以嵌套定義,隨時調用。
Xcode輸入 inline 可快速產生(快速鍵)
1.2 block的格式
如果block沒有參數, 那麼^後面的()可以省略
1.3 給block類型取別名(類比函數指標)
變數的名稱就是類型名稱(即別名)
1.4 block的應用情境
當前面代碼塊一樣,後面代碼塊一樣,中間的代碼塊不一樣,中間的代碼塊就用block。
1.5 block的注意事項
- block中可以定義和外界同名的變數,但是在block中訪問的是block中定義的變數(就近原則,和函數一樣)
(1)在代碼塊中可以直接存取和修改非棧區的變數(使用的是同一個變數)
(2)棧區的變數可以訪問,但預設不能修改(使用的是不同的變數,實際上訪問的是自己拷貝的值)
block中的變數和外界的局部變數並不是同一個變數,block會將外界的變數拷貝一份到堆記憶體中
block中使用的外界變數是copy的,所以在調用之前修改外界變數的值,不會影響到block中copy的值
(3)在代碼塊中修改局部變數編譯不通過。怎麼在代碼塊中修改局部變數呢?在局部變數前面加上關鍵字:__block
1.6 面試題:block是儲存在堆中還是棧中?
- 預設情況下block儲存在棧中,如果對block進行一個copy操作,block會轉移到堆中
- 如果block在棧中, block中訪問了外界的對象, 那麼不會對對象進行retain操作
- 如果block在堆中, block中訪問了外界的對象, 那麼會對外界的對象進行一次retain
1.7 block的記憶體泄露體現
block在copy時都會對block內部用到的對象進行強引用(ARC)或者retainCount增1(非ARC)。
在ARC與非ARC環境下對block使用不當都會引起循環參考問題。
一般表現為:
某個類將block作為自己的屬性變數,然後該類在block的方法體裡面又使用了該類本身,簡單說就是
1)MRC情況下,用__block可以消除循環參考。
2)ARC情況下,必須用弱引用才可以解決循環參考問題,iOS5之後可以直接使用__weak,之前則只能使用__unsafe_unretained了,__unsafe_unretained缺點是指標釋放後自己不會置空。
什麼時候棧上的Block會複製到堆呢?
- 調用Block的copy執行個體方法時
- Block作為函數傳回值返回時
- 將Block賦值給附有__strong修飾符、id類型的類或Block類型成員變數時
- 在方法名中含有usingBlock的Cocoa架構方法或GCD的API中傳遞Block時
block很多的用處是跨越兩個類來使用的。
實現兩個頁面之間的傳值:
- 通過“協議/代理”實現兩個頁面之間傳值
- 使用block作為property,實現兩個頁面之間傳值
面試題: