Block笔记(一)

什么是block

Blocks是C语言的扩充功能,可以用一句话来表示Blocks的扩充功能:带有自动变量(局部变量)匿名函数

所谓匿名函数就是不带有名称的函数。C语言的标准不允许存在这样的函数。例如以下源码:

int func (int count);

它声明了名称为func的函数。下面的源码中为了调用函数,必须使用该函数的名称func

int result = func(10);

如果像下面这样,使用函数指针来代替直接调用函数,那么似乎不用知道函数名也能够使用该函数。

int result = (*funcptr)(10);

但其实使用函数指针也仍需要知道函数名称。

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

而通过Blocks,源代码中就能够使用匿名函数,即不带函数名称的函数。对于程序员来说,命名占用了很大比重,函数名,变量名,方法名,属性名,类名和框架名等都必须具备,而能够编写不带名称的函数对于程序员来说相当具有吸引力。

现在我们知道了匿名函数的概念。那么带有自动变量值又是什么呢?我们先来回顾一下在C语言函数中可能使用的变量
自动变量(局部变量)
函数的参数
静态变量(静态局部变量)
静态全局变量
全局变量
其中在函数的多次调用之间能够传递值的变量有,静态变量(静态局部变量)静态全局变量全局变量

虽然这些变量的作用域不同,但在整个程序当中,一个变量总保持在一个内存区域。因此虽然多次调用函数,但该变量值总保持不变,在任何时候以任何状态调用,使用的都是同样的变量值。

C++和Objective-C使用类可保持变量值且能够多次持有该变量自身。它会声明持有成员变量的类,由类生成的实例对象保持该成员变量的值。但是声明并实现C++,Objective-C的类增加了代码的长度。这时我们就要用到Blocks了。Blocks提供了类似由C++和Objective-C类生成实例或对象来保持变量值的方法。

Block语法

完整形式的Block语法与一般的C语言函数定义相比,仅有两点不同。没有函数名,带有“^”。Block语法的BN范式如下:
^ 返回值类型 参数列表 表达式
例如以下形式:

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

Block的语法可以省略很多东西,我们可以省略其返回值,如果不使用参数,我们也可以省略其参数列表返回值类型以及参数列表均被省略的Block语法应该是最常见的记述方式。

Block类型变量

在Block语法下,可将Block语法赋值给声明为Block类型的变量中,即源代码中一旦使用Block语法就相当于生成了可赋值给Block类型变量的“值”。Block中由Block语法生成的值也被称为“Block”。“Block”既指源代码中的Block语法,也指由Block语法所生成的值

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

在日常开发中我们会经常使用typedef来声明Block类型的变量

typedef void (^myTestBlock)(NSString *参数1,NSString *参数2);

调用

self.myTestBlock(参数1, 参数2);

取得回调

self.myTestBlock = ^(NSString *参数1, NSString *参数2) {

    };
截获自动变量值

我们之前已经了解到了带有自动变量(局部变量)匿名函数中的匿名函数,那么带有自动变量值究竟是什么呢?其实它在Block中表现为“截获自动变量值”。实例如下:

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

Blocks中,Block表达式截获所使用的自动变量的值,即保持该自动变量瞬间值,所以在执行Block语法后,即使改写Block中使用的自动变量的值也不会影响Block执行时自动变量的值。

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

执行结果并不是改写后的值,在Block执行时这些值被保存,从而在执行块时使用,这就是自动变量值的截获。

_ _block说明符

实际上,自动变量值截获只能保存执行Block语法瞬间的值。保存后就不能改写该值,我们尝试改写截获的自动变量值,看看会出现什么结果。

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

该段代码会产生编译错误。

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;
}

执行结果:

val = 1
总结

这一篇先讲解了一些block的概念,规范,功能以及一些用法,下一篇将着重记录Block的实现,在深究其原理前先明白block的相关特性将对后续的学习有很大的帮助。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容