(一)Blocks基礎(chǔ)

一、Blocks概要

1.1 什么是Blocks

Blocks是C語言的擴(kuò)充功能:帶有自動(dòng)變量(局部變量)的匿名函數(shù)

C語言代碼

int buttonId ;

void buttonCallback(int event) 
{
    printf("buttonId:%d event=%d\n",buttonId, event);
}

void setButtonCallbacks()
{
    for (int i = 0;i < BUTTON_MAX;i++) {
        buttonId = i;
        setButtonCallback(BUTTON_IDOFFSET + i, &buttonCallback);
    }
}

說明:本段代碼為了設(shè)置每個(gè)按鈕的buttonId,可見在C語言中攀痊,需要有名函數(shù)蜈七,需要全局變量藻懒。

Block實(shí)現(xiàn)

void setButtonCallbacks()
{
    for (int i = 0;i < BUTTON_MAX;i++) {
        buttonId = i;
        setButtonCallbackUsingBlock(BUTTON_IDOFFSET + i, ^(int event){
            printf("buttonId:%d event=%d\n", i, event);
        });
    }
}

說明:本段代碼將“帶有自動(dòng)變量i值的匿名函數(shù)”設(shè)置為按鈕的回調(diào)转培。使用Blocks可以不用聲明C++和Object-C類唾糯,也沒有使用靜態(tài)變量诚啃、靜態(tài)全局變量或全局變量的問題淮摔,也沒有使用函數(shù)名。

OC中Block在其他程序語言中的名稱如下圖

程序語言 Block名稱
C + Blocks Block
Smalltalk Block
Ruby Block
LISP Lambda
Python Lambda
C++11 Lambda
Javascript Anonymous function

二始赎、 Blocks模式

2.1 Block 語法

上節(jié)的代碼Block語法如下:

^(int event){
    printf("buttonId:%d event=%d\n", i, event);
}

實(shí)際上和橙,該Block語法使用了省略模式,完整如下:

^ void (int event){
    printf("buttonId:%d event=%d\n", i, event);
}

Block語法如下:
^ 返回值類型 參數(shù)列表 表達(dá)式

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

雖然上面出現(xiàn)過省略模式造垛,但Block語法可省略好幾個(gè)項(xiàng)目胃碾。

  1. 省略返回類型
    ^ 參數(shù)列表 表達(dá)式

舉例:
^ (int count) {return count + 1;}

如果表達(dá)式中有return,返回類型就使用該返回值的類型筋搏,這里的返回類型就是Int仆百,如果沒有ruturn,返回類型就是void

  1. 省略返回類型和參數(shù)列表
    ^ 表達(dá)式

舉例:
^ {printf("Blocks\n");}

2.2 Block類型變量

  1. 定義一個(gè)block類型的變量
int (^blk)(int) = ^(int count){return count + 1;};
blk(10);//11
  1. 函數(shù)中傳遞block參數(shù)
- (void)func:(int (^)(int param))block {
    NSLog(@"%d",block(10));//11
}

[self func:^int(int param) {
    return param + 1;
}];
  1. block參數(shù)作為返回值
- (int (^)(int param))functionBlock {
    return ^(int param){return param + 1;};
}

NSLog(@"%d",self.functionBlock(10));//11
  • 劃重點(diǎn)
    我們可以使用typedef int(^blk)(int); 來聲明一個(gè)blk的類型變量

聲明后的block2奔脐、3變成如下形式,是不是感覺這種方式更加的程序員俄周,blk就好像NSString *一樣對變量進(jìn)行類型聲明

- (void)func:(blk)block {
    NSLog(@"%d",block(10));
}
- (blk)functionBlock {
    return ^(int param){
        return param + 1;
    };
}

2.3截獲自動(dòng)變量值

int val = 10;
void (^blk)(void) = ^{
    NSLog(@"%d",val);
};
val = 20;
blk();
NSLog(@"%d",val);//10

block中,block表達(dá)式解惑所使用的自動(dòng)變量val的值髓迎,即保存該自動(dòng)變量的瞬間值峦朗,這些值在執(zhí)行塊時(shí)使用,這就是自動(dòng)變量值的截獲排龄。

2.4__block說明符

如果在2.3中我們在block塊中修改val的值會如何呢波势?編譯器會產(chǎn)生編譯錯(cuò)誤。但很多時(shí)候我們需要修改自動(dòng)截獲的變量的值并讓其發(fā)生改變橄维,我們該如何解決呢尺铣?很簡單,在需要修改的變量前面加上__block說明符即可争舞。

__block int val = 10;
void (^blk)(void) = ^{
    NSLog(@"%d",val);//20
    val = 30;
    NSLog(@"%d",val);//30
};
val = 20;
blk();
NSLog(@"%d",val);//30

使用__block就可以在block中進(jìn)行賦值凛忿,或者在block外面修改自動(dòng)變量的值,被修飾的變量也稱為__block變量竞川。

如果沒有被__block修飾店溢,只要不對變量進(jìn)行賦值操作叁熔,是不會報(bào)編譯錯(cuò)誤的,而且調(diào)用block塊中的對象調(diào)用自己的方法也是沒有問題的,如下面所示:

id array = [NSMutableArray array];
void (^blk)(void) = ^ {
    id obj = [[NSObject alloc] init];
    [array addObject:obj];
};
blk();
  • 注意
    在block中使用指針時(shí)需要特別小心床牧,因?yàn)閎lock截獲自動(dòng)變量的方法中并沒有實(shí)現(xiàn)對C語言數(shù)組的截獲荣回。

下面這段代碼編譯會報(bào)錯(cuò)

const char text[] = "hello";
void (^blk)(void) = ^{
    printf("%c\n",text[2]);
};
blk();

使用指針可以解決該問題:

const char *text = "hello";
void (^blk)(void) = ^{
    printf("%c\n",text[2]);
};
blk();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市戈咳,隨后出現(xiàn)的幾起案子心软,更是在濱河造成了極大的恐慌,老刑警劉巖除秀,帶你破解...
    沈念sama閱讀 212,029評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糯累,死亡現(xiàn)場離奇詭異,居然都是意外死亡册踩,警方通過查閱死者的電腦和手機(jī)泳姐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,395評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來暂吉,“玉大人胖秒,你說我怎么就攤上這事∧降模” “怎么了阎肝?”我有些...
    開封第一講書人閱讀 157,570評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肮街。 經(jīng)常有香客問我风题,道長,這世上最難降的妖魔是什么嫉父? 我笑而不...
    開封第一講書人閱讀 56,535評論 1 284
  • 正文 為了忘掉前任沛硅,我火速辦了婚禮,結(jié)果婚禮上绕辖,老公的妹妹穿的比我還像新娘摇肌。我一直安慰自己,他們只是感情好仪际,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,650評論 6 386
  • 文/花漫 我一把揭開白布围小。 她就那樣靜靜地躺著,像睡著了一般树碱。 火紅的嫁衣襯著肌膚如雪肯适。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,850評論 1 290
  • 那天赴恨,我揣著相機(jī)與錄音疹娶,去河邊找鬼。 笑死伦连,一個(gè)胖子當(dāng)著我的面吹牛雨饺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惑淳,決...
    沈念sama閱讀 39,006評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼额港,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了歧焦?” 一聲冷哼從身側(cè)響起移斩,我...
    開封第一講書人閱讀 37,747評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎绢馍,沒想到半個(gè)月后向瓷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體扛施,經(jīng)...
    沈念sama閱讀 44,207評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嚼鹉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,536評論 2 327
  • 正文 我和宋清朗相戀三年践磅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了玩焰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哗伯。...
    茶點(diǎn)故事閱讀 38,683評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡圆到,死狀恐怖雇锡,靈堂內(nèi)的尸體忽然破棺而出壳炎,到底是詐尸還是另有隱情搁痛,我是刑警寧澤长搀,帶...
    沈念sama閱讀 34,342評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站鸡典,受9級特大地震影響源请,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜彻况,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,964評論 3 315
  • 文/蒙蒙 一谁尸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疗垛,春花似錦症汹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,772評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泽裳,卻和暖如春瞒斩,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涮总。 一陣腳步聲響...
    開封第一講書人閱讀 32,004評論 1 266
  • 我被黑心中介騙來泰國打工胸囱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人瀑梗。 一個(gè)月前我還...
    沈念sama閱讀 46,401評論 2 360
  • 正文 我出身青樓烹笔,卻偏偏與公主長得像裳扯,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子谤职,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,566評論 2 349

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