《Objective-C 高級編程》第一篇:Block概要

本系列文章主要是對《Objective-C 高級編程》這本書做的讀書筆記總結(jié),除了這本書中的內(nèi)容以外钳恕,也加上了自己對開發(fā)技術(shù)的理解和一些個人的經(jīng)驗分享。

一、什么是Blocks

1.1 Blocks概要

Blocks是C語言的擴(kuò)充功能睬关,是帶有局部變量的匿名函數(shù)(匿名其實就是沒有名稱的函數(shù),C語言標(biāo)準(zhǔn)不允許匿名函數(shù))

例如:這里聲明了一個名稱為func的函數(shù)

int func (int count);

為了調(diào)用該函數(shù)毡证,必須使用該函數(shù)的名稱

int  result = func (10);

如果像下面這樣电爹,使用函數(shù)指針來代替直接調(diào)用函數(shù),那么不需要使用函數(shù)名也能夠使用該函數(shù)

int  result = (*funcPtr) (10);

但其實使用函數(shù)指針也仍然需要知道函數(shù)名稱料睛。例如以下丐箩,在賦值給函數(shù)指針時摇邦,若不使用函數(shù)的名稱,就取法取得該函數(shù)的地址屎勘。

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

而通過Blocks施籍,源代碼中就能夠使用匿名函數(shù)。

匿名函數(shù)大家已經(jīng)知道了概漱,那么現(xiàn)在讓我們來看一下C語言中可能使用的變量有哪些 :

  • 局部變量
  • 函數(shù)參數(shù)
  • 靜態(tài)全局變量
  • 靜態(tài)局部變量
  • 全局變量

1.2 Blocks語法

下面我們來詳細(xì)講解一下帶有局部變量值的匿名函數(shù)Blocks的語法:

^ 返回值類型 參數(shù)列表 表達(dá)式

以下定義表明這是一個表示沒有返回類型丑慎,并且參數(shù)為int型的Block
^ void (int a, int b) {
  // do sth
}

如上所示:完整形式的Blocks和C語言的函數(shù)定義區(qū)別為:

  • 沒有函數(shù)名 (匿名函數(shù))
  • 沒有 ^

溫馨小貼士:因為OS X,iOS 應(yīng)用程序的源代碼中大量使用Block瓤摧,所以插入該記號便于查找竿裂。

block可以省略返回類型

省略返回類型的語法為: ^ 參數(shù)列表 表達(dá)式

^ void (int a, int b) {表達(dá)式}

等價于

^ (int a, int b) {表達(dá)式}

其次,如果不使用參數(shù)照弥,block也可以省略參數(shù)列表

語法為: ^ 表達(dá)式

^ {
  // 說點什么吧腻异,少年
}

1.3 Block與C函數(shù)對比

int func (int count) 
{
  return count + 1;
}
// 函數(shù)func的地址賦值給函數(shù)指針變量funcPtr
// 在block語法下可將block賦值給聲明為block類型的變量
int (*funcPtr) (int) = &func
int (^blockName) (int)

與前面的使用函數(shù)指針的源代碼對比可知,聲明block類型變量僅僅是將聲明函數(shù)指針類型變量 * 變?yōu)?^

int (^block) (int) = ^ (int count) {
    return count + 1;
}

block類型變量與c語言變量相同产喉,block也可以作為函數(shù)參數(shù)傳遞或者函數(shù)的返回值

  • 作為函數(shù)參數(shù)
void func ( int (^block) (int) ) {
  //
}
  • 作為函數(shù)的返回值
int (^func()) (int) {
  //
  return ^ (int count) {
      return count + 1;
  };
}

由上面源代碼可以看出在使用block變量時捂掰,記錄方式非常復(fù)雜。我們可以像使用函數(shù)指針類型那樣曾沈,使用 typedef來解決

  typedef int (block_t) (int)

我們來對比以下

// 沒有定義前
void func ( int (^block) (int) ) {

}

// 定義后
void func (block_t block) {

}

另外这嚣,Block調(diào)用 和 C語言中使用函數(shù)指針調(diào)用函數(shù)的方法幾乎完全相同。

int result = (*funcPtr)(10);
int result = block(10);

也可以使用指向block類型變量的指針調(diào)用block

typedef int (^block_t) (int)

block_t block = ^ (int count) {
  return count + 1;
}

block_t *blockPtr = █

(* blockPtr)(10);

1.4 截獲局部變量值以及__block說明符的使用

1.4.1 截獲局部變量值

截獲局部變量值是指保存執(zhí)行block語法瞬間的值塞俱,并且保存后就不能修改變量值姐帚。

int val = 0;

void (^block) (void) = ^ {
  NSLog(@"val = %d", val);
}

val = 1;

block();

執(zhí)行上面源代碼,打印val的值為0障涯。這是因為在block中截獲了局部變量的值罐旗,即保存了該變量的瞬間值。所以即使更改了變量的值也不會影響block的打印唯蝶。

1.4.2__block說明符的使用

執(zhí)行下面源代碼九秀,會產(chǎn)生編譯錯誤。

int val = 0;

void (^block) (void) = ^ {
  val = 1;
}

block();

NSLog(@"val = %d", val);

向截獲的變量直接賦值會發(fā)生編譯錯誤粘我,但使用截獲的值卻不會報錯鼓蜒。

id array = [NSMutableArray array];

void (^block) (void) = ^ {
  id obj = [[NSObject alloc] init];
  [array addObject:obj];
}

block();

若想在block中修改局部變量的值,需要在該自動變量前加 __block 說明符征字。

__block int val = 0;

void (^block) (void) = ^ {
  val = 1;
}

block();

NSLog(@"val = %d", val);

源代碼的執(zhí)行結(jié)果為:val = 1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末都弹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子匙姜,更是在濱河造成了極大的恐慌畅厢,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氮昧,死亡現(xiàn)場離奇詭異框杜,居然都是意外死亡浦楣,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門霸琴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椒振,“玉大人,你說我怎么就攤上這事梧乘∨煊” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵选调,是天一觀的道長夹供。 經(jīng)常有香客問我,道長仁堪,這世上最難降的妖魔是什么哮洽? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮弦聂,結(jié)果婚禮上鸟辅,老公的妹妹穿的比我還像新娘。我一直安慰自己莺葫,他們只是感情好匪凉,可當(dāng)我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捺檬,像睡著了一般再层。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上堡纬,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天聂受,我揣著相機(jī)與錄音,去河邊找鬼烤镐。 笑死蛋济,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的炮叶。 我是一名探鬼主播瘫俊,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼悴灵!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起骂蓖,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤积瞒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后登下,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茫孔,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡叮喳,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了缰贝。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馍悟。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖剩晴,靈堂內(nèi)的尸體忽然破棺而出锣咒,到底是詐尸還是另有隱情,我是刑警寧澤赞弥,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布毅整,位于F島的核電站,受9級特大地震影響绽左,放射性物質(zhì)發(fā)生泄漏悼嫉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一拼窥、第九天 我趴在偏房一處隱蔽的房頂上張望戏蔑。 院中可真熱鬧,春花似錦鲁纠、人聲如沸总棵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽彻舰。三九已至,卻和暖如春候味,著一層夾襖步出監(jiān)牢的瞬間刃唤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工白群, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留尚胞,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓帜慢,卻偏偏與公主長得像笼裳,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子粱玲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,601評論 2 353

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