一: block的基礎用法
block聲明: int(^blockDemon)(inta,intb) ,其中int : 為返回值,
blockDemon: 為block變量名稱,
(int a, int b): 為block接收參數(shù)
block實現(xiàn):^(int a, int b){? ? ? ? ? ?returna + b;
}
截獲自動變量值:
block會自動保存變量的瞬間值,盡管對變量進行重新賦值操作,block 內(nèi)部依舊會保存變量原先值
__block說明符號:
自動變量截獲的值為block聲明時刻的瞬間值蛋哭,
保存后就不能改寫該值(但可讀)悼泌,如需對自動變量進行重新賦值盯孙,需要在變量聲明前附加__block說明符建峭,這時該變量稱為__block變量召庞。
自動變量值為一個對象的特殊情況(沒有使用__block),當自動變量為一個類的對象,且沒有使用__block修飾時静稻,雖然不可以在Block內(nèi)對該變量進行重新賦值放椰,但可以修改該對象的屬性。
二: block的循環(huán)引用
最簡單的例子:
[self.teacher?requestData:^(NSData?*data)?{
????self.name?=?@"case";
}];
self強引用了teacher,而teacher又強引用了一個block,而block在回調(diào)時又強引用了self,形成一個保留環(huán),即self-->teacher-->block-->self,最終導致內(nèi)存泄露寺擂。
一般的解決辦法:
__weak?typeof(self)?weakSelf?=?self;
????[self.teacher?requestData:^(NSData?*data)?{
????????typeof(weakSelf)?strongSelf?=?weakSelf;
???????strongSelf.name?=?@"case";
????}];
通過__weak修飾符,這樣就打破了保留環(huán),即self-->teacher-->block-->weakSelf暇务。
三: block的結構與實質(zhì)
使用block的時候,編譯器對block做了什么:
經(jīng)過分析工具clang后: