block的简单理解(1)

一. block类型的变量的声明.

返回值类型(^block变量名)(参数列表);

void (^myBlock)();

表示声明了1个block类型的变量变量名叫做myBlock

这个myBlock变量只能存储无返回值无参数的代码段.

void (^myBlock1)(int num1,int num2);

表示声明了1个block类型的变量叫做myBlock1

这个myBlock1变量之中可以存储无返回值带两个int类型的参数的代码段.

int (^myBlock2)(int num1,int num2);

二. block变量的初始化.

2).如何写1个符合要求的代码段.

语法:

^返回值类型(参数列表){

代码;

};

a.无参数无返回值的代码段.

^void(){

NSLog(@"呵呵1");

NSLog(@"随便2");

};

完全可以将这个代码段通过赋值符号存储到符合要求的block变量之中.

void (^myBlock1)();

myBlock1 =   ^void(){

NSLog(@"呵呵1");

NSLog(@"随便2");

};

当然完全可以在声明block变量的同时直接赋值.

b.无返回值,有参数的代码段的书写.

^void(int num1,int num2){

int num3 = nim1 + num2;

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

};

void (^myBlock2)(int num1,int num2) =  ^void(int num1,int num2){

int num3 = nim1 + num2;

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

};

c.有返回值有参数的代码段的书写.

^int(int num1,int num2){

int num3 = num1 + num2;

return num3;

};

int (^myBlock3)(int num1,int num2) = ^int(int num1,int num2){

int num3 = num1 + num2;

return num3;

};

为block变量赋值代码段的时候,代码段必须符合block变量的返回值和参数的要求.

否则就会报错.

三.执行存储在block类型变量中的代码.

1).如何执行?

在要执行的地方加上代码:             block变量名();

如果存储在block变量中的代码段有参数,那么给参数就可以了.

如果有返回值,使用1个相应类型的变量接收返回值就可以了.

6.使用block注意小点.

1).如果代码段没有参数.那么代码段可以省略表示参数列表的小括弧.

void (^myBlock)() = ^void{

NSLog(@"呵呵");

};

2).如果声明block变量的时候,要求代码块带参数.那么在声明block变量的时候.可以只写参数类型,省略参数名称.

但是代码段是必须要写参数名字的.

void (^myBlock)(int,int) = ^void(int num1,int num2){

NSLog(@"%d + %d = %d",num1,num2,num1+num2);

};

3).代码段的返回值类型可以省略.

int (^myBlock)(int,int) = ^(int num1,int num2){

return num1 + num2;

};

如果代码段没有指定返回类型.那么这个代码段的返回值类型就是return回去的数据的类型.

如果没有return那么这个代码段就的返回值就是void.

void (^block1)() = ^{

.....

};

7.使用typedef将复杂的block定义简化.

1).遇到的问题.

如果我们希望定义1个无返回值无参数的block变量.

void (^myBlock1)();

如果再希望定义1个呢?

void (^myBlock2)();

如果再希望定义1个呢?

void (^myBlock2)();

...........

你有没有发现,每次定义block变量要使用好长的1段代码,忒麻烦.

2).我们学习过typedef给已经存在的类型取1个别名.

我们可以为1个指定要求的block取1个短别名.然后使用这个别名声明多个要求一致的block变量.

废话不说,看例子.

typedef void (^newType)();

代表为返回值为void并且没有参数的block类型定义了1个别名叫做newType.

如果我们想声明1个没有返回值并且参数的block.直接使用别名newType就可以定义.

比如:

newType myBlock;

首先,myBlock是1个变量.1个block类型的变量.这个变量要求存储的代码段无返回值并且没有参数.

所以,可以像下面这样初始化.

myBlock = ^{

NSLog(@"呵呵");

};

调用按原来的就方式就可以调用.

myBlock();

------------再次举例-----------------

typedef int (^newType)(int,int);

代表为返回值为int类型,参数有两个int类型的参数的block类型定义了1个别名叫做newType.

如果我们要声明1个返回值为int,并且参数是两个int类型的block变量的时候,

就可以使用newType来直接简单声明

newType sumBlock = ^(int num1,int num2){

return num1 + num2;

};

调用block

int sum = sumBlock(10,20);

四. block访问外部变量.

1).全局变量.局部变量. block内部变量.重名及各自的作用域.

2).默认情况下,block内部可以取外部的变量的值.

但是无法修改外部变量的值.

可以修改全局变量,但是无法修改外部的局部变量.

3).如果允许外部变量的值在block内部可以被修改,那么就将外部变量使用__block修饰.

默认情况下block外部的局部变量只允许在block内存的取值访问,不允许在block内部改值.

如果就是要允许外部的局部变量可以改

用__block来修饰外部的局部变量.


五,block作为函数的参数

     1. block是1个数据类型. 所以block类型完全可以作为函数的参数或者返回值.

2. block作为函数的参数.  (他的作用就是让调用者自己控制代码的实现,比如实现两个数的和与乘积)

1). 形参就直接声明1个符合要求的block变量就可以了.如果觉得恶心,可以使用typedef简化定义.

2). 实参代码段的要求必须要和形参的要求一致.

如果形参是1个无返回值无参数的block 那么实参的代码段也必须要符合这个要求.

3). 在传值的时候.

a. 先将符合要求的代码段存储在1个block变量之中 然后再传递block变量.

b. 也可以直接传递符合要求的代码段.

3. block作为函数的参数可以实现的效果.

可以让调用者传递1段代码到函数的内部. 在函数的内部执行这段代码.

void sum(int a, int b, void(^block)(int c)){

int sum = a + b;

// 回调block

block(sum);

}

// 调用函数

sum(20, 10, ^(int c) {

NSLog(@"sum=%d",c);

});

上面只是一个小例子,在第申明函数的内部,把求和的结果放在了block里面,相当于求和的代码块放在了block里面,当我们调用函数的时候,就可以使用这个存放在block里面的代码块。

3. block与函数的异同

1). 相同点: 都可以封装1段代码在其中.

2). 不同点:

a. block是1个数据类型. 而函数就是函数.

b. block可以作为函数的参数传递。而函数不能直接作为参数传递.

c. block可以嵌套.函数不能嵌套定义.

4 ,blcok作为函数的返回值

步骤是:1 定义一个新的blcok数据类型

                2 新的block数据类型作为函数的返回值

                3 调用函数

                4 回调block 

//相当于定义一个void类型的无参数的block数据类型    新的数据类型名为NewType

typedef void (^NewType)();   // 第一步


NewType test()     // 第二步

{

void (^block)() = ^{

NSLog(@"哈哈哈哈哈哈哈");

NSLog(@"呵呵呵呵呵呵呵");

};

return block;

}

// 调用函数

NewType bType =  test();    // 第三步

bType();    // 第四步

再深入理解的Block,可以看下下面3篇文章,写的很好。


http://my.oschina.net/leejan97/blog/268536

http://my.oschina.net/leejan97/blog/262855

http://my.oschina.net/leejan97/blog/209762

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

推荐阅读更多精彩内容