转载自:http://www.cnblogs.com/lzz900201/archive/2013/04/17/3025340.html

block是个什么玩意儿

Block是Apple Inc.为C、C++以及Objective-C添加的特性,使得这些语言可以用类lambda表达式的语法来创建闭包 ——维基百科

A block is an anonymous inline collection of code, and sometimes also called a "closure". ——Apple文档

闭包就是能够读取其它函数内部变量的函数。

这里简单总结一下用法。block的用法有很多种,最常用的有 回调 和 遍历 。这篇主要说 回调

  1. 回调

    什么是回调

    在计算机程序设计中,回调函数,或简称回调(Callback),是指通过函数参数传递到其它代码的,某一块可执行代码的引用。这一设计允许了底层代码调用在高层定义的子程序。 ——维基百科

    回调就是说,我一个操作执行完成之后,提供给调用者一个接口,供调用者定义一些操作。obj-C的代理模式就是典型的回调。

    举个简单的block例子:

     @interface People : NSObject
    
     -(void)runningOutOfMoneyUsingBlock:(void (^)(void))aBlok;
    
     @end
    
     @implementaiton People
    
     -(void)runningOutOfMoneyUsingBlock:(void (^)(void))aBlok
    {
    NSLog(@"I have run out of my money");
    aBlock(); //(1)
    } @end

    这个时候, 就定义了一个带block参数的方法。这是一个很简单的block参数, 没有返回值, 没有参数。

    当我们调用这个方法的时候,只需这样操作:

     Peopeo *aPeople = [[People alloc] init]];
    [aPeople runningOutOfMoneyUsingBlock:^{ NSLog(@"Earn more money!"); }];

    这时在执行People类方法的时候,执行结果如下:

     “I have run out of my mondy”
    "Earn more money!"

    很好理解,People的类方法有一个block参数。调用者在调用该方法的时候为block参数定义了若干操作(这里是输出一句话),然后将这些操作作为参数传递给类方法内部执行.调用者所定义的这些操作执行的位置,取决于"(1)"所处的位置。

    如果将类方法的实现改变为:

     -(void)runningOutOfMoneyUsingBlock:(void (^)(void))aBlok
    {
    aBlock(); //(1)
    NSLog(@"I have run out of my money");
    } @end

    那么运行结果就会变为:

     "Earn more money!"
    “I have run out of my money”

    下面来说一说block 带参数 的情况,有People类方法定义如下:

     @interface People : NSObject
    
     -(void)runningOutOfMoneyUsingBlock:(void (^)(int a, int b))aBlok;
    
     @end
    
     @implementaiton People
    
     -(void)runningOutOfMoneyUsingBlock:(void (^)(int a, int b))aBlok
    {
    NSLog(@"I have run out of my money");
    int a = 10;
    int b = 50
    aBlock(a,b); //(2)
    } @end

    在这个类方法中,对之前的People类方法的block参数进行了扩展,加入了两个整形参数:a和b。在调用block之前为a和b赋值并且传给了block,形如(2)。

    这个时候,当我们在调用这个类方法的时候,就会出现这样的情况:

     Peopeo *aPeople = [[People alloc] init]];
    [aPeople runningOutOfMoneyUsingBlock:^(int a, int b){ NSLog(@"a = %d, b = %d", a, b); }];

    执行结果如下:

     "Earn more money!"
    "a = 10, b = 50"

    不难看出,People将自己内部的两个局部变量, 通过block传递给了调用者。这一点很好理解,想想我们经常使用的 代理方法 就可以了。

    以UITableView的代理方法为例,代理方法定义如下

     - (void)tableView(UITableView *):tableView didSelectRowAtIndexPath:(NSIndexPath)indexPath;

    这个方法用来给某个section指定行数。私以为这个方法可以换为如下block实现。

     @interface UITableView (WithBlock)
    
     -(void)didSelectRowAtIndexPathUsingBlock:(void (^)(UItableView *tableView, NSIndxPath *indexPath))selectBlock;
    
     @end
    
     @implementation UITableView (WithBlock)
    
     -(void)didSelectRowAtIndexPathUsingBlock:(void (^)(UItableView *tableView, NSIndxPath *indexPath))selectBlock
    {
    //some other code
    ...
    if(selectBlock) {
    selectBlock(self, indexPath);
    } …
    //some other code
    } @end

    好吧, 我承认这里给出这样的方法有点儿蹩脚,仅仅是为了对比Block和代理的相似之处。回想一下代理的实现,block是一样的原理。

    block还可以有返回值,将block在调用者处执行的结果返回给方法本身。例如,再对以上实例方法进行扩展,代码如下:

      @interface People : NSObject
    
     -(void)runningOutOfMoneyUsingBlock:(int (^)(int a, int b))aBlok;
    
     @end
    
     @implementaiton People
    
     -(void)runningOutOfMoneyUsingBlock:(int (^)(int a, int b))aBlock
    {
    NSLog(@"I have run out of my money");
    int a = 10;
    int b = 50
    int m = 0;
    if(aBlock)
    {
    m = aBlock(a,b); //(2)
    }
    NSLog(@"aBlock的返回值为:%d",m); } @end

    调用该方法:

     [aPeople runningOutOfMoneyUsingBlock^(int a, int b){
    return a + b;
    }];

    执行结果为:

     "I have run out of money"
    "aBlock的返回值为:60"

Block 朴实理解的更多相关文章

  1. 对于block的理解,block的面试题

    1.block跟swift中的闭包(closure)基本一样,都常用于值的回调,特别是在多线程的网络请求回调中,使用起来极为方便. 2.block的开头是"^",接着是由小括号所报 ...

  2. Objective-C block深入理解

    一.block是什么? block是带有自动变量(局部变量)的匿名函数.它是C语言的扩展功能,C语言标准并不支持block. block是Objective-C的闭包实现,正如C++中的Lambda表 ...

  3. inode和block的理解

    什么是inode和block? 所谓的inode就是索引节点(index node)的意思,在每一个存储设备被格式化创建文件系统后,所有的文件大致被分为了两部分,分别是inode和block. 其中i ...

  4. Block使用

    1.对block的理解 >  block是iOS4.0之后出现的,是仿照java中匿名函数所创造的,它是c级别的语法,效率比协议-代理高 >  block的是一个匿名函数(没有名字的函数) ...

  5. iOS-重回block小白之路

    在我刚刚接触iOS开发的时候,是通过MJ老师讲的OC基础入门的,iOS圈的人应该基本都知道MJ大神吧,即便如此大神,讲解完block之后我依然感觉晕晕乎乎的,直到后来真正进公司做项目,依然感觉这是自己 ...

  6. Swift 05.Block

    Swift的函数用法还真是灵活.但是个人感觉更灵活的还是闭包. swift闭包的概念大抵相当于OC的block的概念.如果对于block的理解很透彻的话,闭包的原理性的东西还是很好理解的. 剩下的就是 ...

  7. block(代码块)的介绍以及使用方法和变量之间的关系

    http://blog.csdn.net/menxu_work/article/details/8762848 block(代码块)的介绍以及使用方法和变量之间的关系 block(代码块)的介绍以及使 ...

  8. Objective-C之Block

    Block基本概念 本小节知识点: [了解]什么是Block [理解]block的格式 1.什么是Block Block是iOS中一种比较特殊的数据类型 Block是苹果官方特别推荐使用的数据类型, ...

  9. 谈Objective-C Block的实现

    来源:http://blog.devtang.com/blog/2013/07/28/a-look-inside-blocks/ 前言 这里有关于block的5道测试题,建议你阅读本文之前先做一下测试 ...

随机推荐

  1. iOS拨打电话

    1,这种方法,拨打完电话回不到原来的应用,会停留在通讯录里,而且是直接拨打,不弹出提示NSMutableString * str=[[NSMutableString alloc] initWithFo ...

  2. 下拉的DIV+CSS+JS二级树型菜单

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. Chapter 1 First Sight——25

    "They are… very nice-looking." I struggled with the conspicuous understatement. 他们都很好看,我与轻 ...

  4. hdu_5807_Keep In Touch(分段dp)

    题目链接:hdu_5807_Keep In Touch 题意: 在Byteland一共有nn个城市,编号依次为11到nn,同时有mm条单向道路连接着这些城市,其中第ii条道路的起点为u_iu​i​​, ...

  5. Git 暂存区的概念

    工作区:我们在电脑里面能看到的目录,也就是我们用git init 命令初始化的那个目录.里面包含要添加文件和需要提交的文件,在这个目录下的文件,修改和变更,我们的git都能感知的到. 版本库:工作区有 ...

  6. Vowel Counting

    Vowel Counting Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) Tota ...

  7. ORACLE里锁有以下几种模式,v$locked_object,locked_mode【转】

    ORACLE里锁有以下几种模式:0:none1:null 空2:Row-S 行共享(RS):共享表锁,sub share 3:Row-X 行独占(RX):用于行的修改,sub exclusive 4: ...

  8. cisco 2950 3550 3750 系列交换机密码破解

    破解密码原则:只删除密码 ,不破坏配置#本文中的#号表示注释的意思#第一步. 连接交换机的console口到终端#第二步. 按住交换机面板上的mode键的同时 插入电源,直到sys灯不闪,常亮再松开m ...

  9. Linux下配置Nginx按天切割日志

    Nginx由于轻巧和高效的设计风格,去掉了一些额外的功能,所以它不像apache那样有自动切割日志. 建立一个脚本文件,并保证这个文件有可执行的权限:1.建立一个文件/root/log.nginx.s ...

  10. docker installation on ubuntu

    Ubuntu Docker is supported on these Ubuntu operating systems: Ubuntu Xenial 16.04 (LTS) Ubuntu Trust ...