Block筆記(一)

什么是block

Blocks是C語言的擴充功能豺瘤,可以用一句話來表示Blocks的擴充功能:帶有自動變量(局部變量)匿名函數(shù)镜廉。

所謂匿名函數(shù)就是不帶有名稱的函數(shù)蜘腌。C語言的標準不允許存在這樣的函數(shù)舍沙。例如以下源碼:

int func (int count);

它聲明了名稱為func的函數(shù)怎栽。下面的源碼中為了調(diào)用函數(shù),必須使用該函數(shù)的名稱func阀捅。

int result = func(10);

如果像下面這樣胀瞪,使用函數(shù)指針來代替直接調(diào)用函數(shù),那么似乎不用知道函數(shù)名也能夠使用該函數(shù)饲鄙。

int result = (*funcptr)(10);

但其實使用函數(shù)指針也仍需要知道函數(shù)名稱凄诞。

int (*funcptr)(int) = &func;
int result = (*funcptr)(10);

而通過Blocks圆雁,源代碼中就能夠使用匿名函數(shù),即不帶函數(shù)名稱的函數(shù)帆谍。對于程序員來說伪朽,命名占用了很大比重,函數(shù)名既忆,變量名驱负,方法名嗦玖,屬性名患雇,類名和框架名等都必須具備,而能夠編寫不帶名稱的函數(shù)對于程序員來說相當(dāng)具有吸引力宇挫。

現(xiàn)在我們知道了匿名函數(shù)的概念苛吱。那么帶有自動變量值又是什么呢?我們先來回顧一下在C語言函數(shù)中可能使用的變量器瘪。
自動變量(局部變量)
函數(shù)的參數(shù)
靜態(tài)變量(靜態(tài)局部變量)
靜態(tài)全局變量
全局變量
其中在函數(shù)的多次調(diào)用之間能夠傳遞值的變量有翠储,靜態(tài)變量(靜態(tài)局部變量)靜態(tài)全局變量橡疼,全局變量援所。

雖然這些變量的作用域不同,但在整個程序當(dāng)中欣除,一個變量總保持在一個內(nèi)存區(qū)域住拭。因此雖然多次調(diào)用函數(shù),但該變量值總保持不變历帚,在任何時候以任何狀態(tài)調(diào)用滔岳,使用的都是同樣的變量值。

C++和Objective-C使用類可保持變量值且能夠多次持有該變量自身挽牢。它會聲明持有成員變量的類谱煤,由類生成的實例對象保持該成員變量的值。但是聲明并實現(xiàn)C++禽拔,Objective-C的類增加了代碼的長度刘离。這時我們就要用到Blocks了。Blocks提供了類似由C++和Objective-C類生成實例或?qū)ο?/code>來保持變量值的方法睹栖。

Block語法

完整形式的Block語法與一般的C語言函數(shù)定義相比寥闪,僅有兩點不同。沒有函數(shù)名磨淌,帶有“^”疲憋。Block語法的BN范式如下:
^ 返回值類型 參數(shù)列表 表達式
例如以下形式:

^int (int count) {return count + 1}

Block的語法可以省略很多東西,我們可以省略其返回值梁只,如果不使用參數(shù)缚柳,我們也可以省略其參數(shù)列表埃脏,返回值類型以及參數(shù)列表均被省略的Block語法應(yīng)該是最常見的記述方式。

Block類型變量

在Block語法下秋忙,可將Block語法賦值給聲明為Block類型的變量中彩掐,即源代碼中一旦使用Block語法就相當(dāng)于生成了可賦值給Block類型變量的“值”。Block中由Block語法生成的值也被稱為“Block”灰追《掠模“Block”既指源代碼中的Block語法,也指由Block語法所生成的值弹澎。

int (^blk)(int) = ^int (int count) {return count + 1}

在日常開發(fā)中我們會經(jīng)常使用typedef來聲明Block類型的變量

typedef void (^myTestBlock)(NSString *參數(shù)1,NSString *參數(shù)2);

調(diào)用

self.myTestBlock(參數(shù)1, 參數(shù)2);

取得回調(diào)

self.myTestBlock = ^(NSString *參數(shù)1, NSString *參數(shù)2) {

    };
截獲自動變量值

我們之前已經(jīng)了解到了帶有自動變量(局部變量)匿名函數(shù)中的匿名函數(shù)朴下,那么帶有自動變量值究竟是什么呢?其實它在Block中表現(xiàn)為“截獲自動變量值”苦蒿。實例如下:

- (void)testBlock{
    int dmy = 256;
    int val = 10;
    void (^blk)(void) = ^{
        NSLog(@"%d,%d",dmy,val);
    };
    val = 2;
    blk();
}

Blocks中殴胧,Block表達式截獲所使用的自動變量的值,即保持該自動變量瞬間值佩迟,所以在執(zhí)行Block語法后团滥,即使改寫Block中使用的自動變量的值也不會影響Block執(zhí)行時自動變量的值。

2018-10-19 15:26:20.873463+0800 testDemo[74354:1089050] 256,10

執(zhí)行結(jié)果并不是改寫后的值报强,在Block執(zhí)行時這些值被保存灸姊,從而在執(zhí)行塊時使用,這就是自動變量值的截獲秉溉。

_ _block說明符

實際上力惯,自動變量值截獲只能保存執(zhí)行Block語法瞬間的值。保存后就不能改寫該值坚嗜,我們嘗試改寫截獲的自動變量值夯膀,看看會出現(xiàn)什么結(jié)果。

int main(){
    int val = 0;
    
    void (^block)(void) = ^{
        val = 1;
    };
    block();
    
    printf("block");
    
    return 0;
}

該段代碼會產(chǎn)生編譯錯誤苍蔬。

Variable is not assignable (missing __block type specifier)

若想在Block語法的表達式中將值賦給在Block語法外聲明的自動變量诱建,需要在該自動變量上附加__block說明符。

int main(){
    __block int val = 0;
    
    void (^block)(void) = ^{
        val = 1;
    };
    
    block();
    
    printf("val = %d\n",val);
    
    return 0;
}

執(zhí)行結(jié)果:

val = 1
總結(jié)

這一篇先講解了一些block的概念碟绑,規(guī)范俺猿,功能以及一些用法,下一篇將著重記錄Block的實現(xiàn)格仲,在深究其原理前先明白block的相關(guān)特性將對后續(xù)的學(xué)習(xí)有很大的幫助押袍。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市凯肋,隨后出現(xiàn)的幾起案子谊惭,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件圈盔,死亡現(xiàn)場離奇詭異豹芯,居然都是意外死亡,警方通過查閱死者的電腦和手機驱敲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門铁蹈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人众眨,你說我怎么就攤上這事握牧。” “怎么了娩梨?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵沿腰,是天一觀的道長。 經(jīng)常有香客問我姚建,道長矫俺,這世上最難降的妖魔是什么吱殉? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任掸冤,我火速辦了婚禮,結(jié)果婚禮上友雳,老公的妹妹穿的比我還像新娘稿湿。我一直安慰自己,他們只是感情好押赊,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布饺藤。 她就那樣靜靜地躺著,像睡著了一般流礁。 火紅的嫁衣襯著肌膚如雪涕俗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天神帅,我揣著相機與錄音再姑,去河邊找鬼。 笑死找御,一個胖子當(dāng)著我的面吹牛元镀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播霎桅,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼栖疑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了滔驶?” 一聲冷哼從身側(cè)響起遇革,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后萝快,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體比原,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年杠巡,在試婚紗的時候發(fā)現(xiàn)自己被綠了量窘。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡氢拥,死狀恐怖蚌铜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嫩海,我是刑警寧澤冬殃,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站叁怪,受9級特大地震影響审葬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奕谭,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一涣觉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧血柳,春花似錦官册、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至根吁,卻和暖如春员淫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背击敌。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工介返, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人愚争。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓映皆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親轰枝。 傳聞我的和親對象是個殘疾皇子捅彻,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容