前几个星期,我利用通知写了一个仿京东选择地址的Demo(http://blog.csdn.net/hbblzjy/article/details/52212879),后来看过一篇文章说,尽量少用通知,因为通知容易占据手机内存,即使你进行了通知移除处理,也不太保险,所以今天再次谈谈Block的使用,之前也写过一篇文章(http://blog.csdn.net/hbblzjy/article/details/51108159)。

首先在阅读本文之前,请尝试写出一下问题:

  1. 声明一个Block,并调用它。
  2. 声明一个Block型的属性。
  3. 声明一个方法,接受一个Block型的参数,并写出调用时传入的Block实参。
  4. 实现一个Block的递归调用(Block调用自己)。
  5. 实现一个方法,将Block作为返回值。

一、概念

首先需要了解的是Block是一个代码块,是一个变量的形式存在的。

二、构成了解

我们需要在函数中声明block,因为是变量的形式,而且存在静态变量形式

类型1:

 NSString* (^blocks)(NSString*)= ^(NSString *str)

    {

        //NSLog(@"this is :%@",str);

        return str;

    };

返回值类型是字符串,如同函数一样,返回值类型写在最前面

^blocks是声明一个代码块,名字叫做blocks

后面括号跟的是参数的类型,如果没有参数返回void,如果有多个参数类型,那么逗号分隔列出

等于号后面的是参数名列表。

因为写的是一个有返回值的block,所以需要return一个与返回值类型相同类型的值,这里返回的是参数字符串

类型2:

int (^david)(int)= ^(int num)

    {

        return num*5;

    };

这里的返回值类型是一个int,代码块名字叫做david,参数是一个int类型的变量

等于号后面是参数列表,执行的语句是return num *5这句话。

因为如上的两个例子都是有返回值的类型,那么我在调用的时候可以直接使用。

例如:

    NSLog(@"this is block:%@",blocks(@"hello"));

    NSLog(@"this is block:%d",blocks(5));

类型3:

void (^david)(void)= ^(void)

    {

            NSLog(@"I am a block code!");

    };

这里只是简单的执行了一句话,调用方法就是直接打印或者当作变量直接使用,形式介绍:

  • return_type 表示返回的对象/关键字等(通常是void)
  • blockName 表示block的名称
  • var_type 表示参数的类型
  • varName 表示参数名称

三、声明一个Block,作为局部变量:

return_type (^blockName)(var_type) = ^return_type (var_type varName) {
    // ...
};
blockName(var);

四、声明一个Block型的属性

注意与局部变量的声明比较,有细微差别,你能指出吗?

@property (copy) return_type (^blockName) (var_type);

五、在定义方法时,声明Block型的形参

这里提供的是Block的定义

- (void)yourMethod:(return_type (^)(var_type))blockName;

六、Block作为实参

调用方法时,传入Block,这里需要的是Block的具体实现

[someObject doSomethingWithBlock: ^return_type (var_type varName)
{
    //...
}];

如果已经定义了局部变量的Block,也可以直接传入名称。

七、匿名Block

Block实现时,如上文的局部变量和实参,等号右边就是一个匿名Block,它没有blockName

^return_type (var_type varName)
{
    //...
};

八、typedef Block

利用typedef简化Block的声明:

typedef return_type (^BlockTypeName)(var_type);

然后可用BlockTypeName定义Block,类似类名的使用方法:

BlockTypeName aBlock = ^return_type (var_type) {
    //...
}

九、内联 Block

这种形式并不常用,匿名Block声明后立即被调用:

^return_type (var_type varName)
{
    //...
}(var);

内联 Block可用于代码分块,提高代码可读性,功能类似大括号的代码块,其它功能非常有限:

{
   //...
}

十、递归调用Block

Block内部调用自身,递归调用是很多算法基础,特别是在无法提前预知循环终止条件的情况下。注意 由于Block内部引用了自身,这里必须使用__block避免保留环问题。

__block return_type (^blockName)(var_type) = [^return_type (var_type varName)
{
    if (returnCondition)
    {
        blockName = nil;
        return;
    }
    // ...
    blockName(varName);
} copy];
blockName(varValue);

十一、Block作为返回值

方法的返回值是一个Block,可用于一些“工厂模式”的方法中:

- (return_type(^)(var_type))methodName
{
    // ...
}

还有很多可参考的文章:

参考:

http://blog.csdn.net/fhbystudy/article/details/17350951

http://stackoverflow.com/questions/10892361/generic-typeof-for-weak-self-references

http://stackoverflow.com/questions/14877415/difference-between-typeof-typeof-and-typeof-objective-c

http://rocry.com/2012/12/18/objective-c-type-of/

http://fuckingblocksyntax.com/ 这是个工具网站,写block的时候会用到。

http://www.jianshu.com/p/dc5ced9bd7e7

iOS开发基础block的形式讲解的更多相关文章

  1. IOS开发基础知识碎片-导航

    1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...

  2. iOS开发关于Block代码错误

    本文永久地址为http://www.cnblogs.com/ChenYilong/p/4052362.html ,转载请注明出处. iOS开发关于Block代码错误 Incompatible bloc ...

  3. iOS开发——总结篇&IOS开发基础知识

    IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...

  4. IOS开发基础环境搭建

    一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包:       ...

  5. iOS开发基础-九宫格坐标(6)

    继续对iOS开发基础-九宫格坐标(5)中的代码进行优化. 优化思路:把字典转模型部分的数据处理操作也拿到模型类中去实现,即将 ViewController 类实现中 apps 方法搬到 WJQAppI ...

  6. iOS开发基础-九宫格坐标(5)

    继续在iOS开发基础-九宫格坐标(4)的基础上进行优化. 一.改进思路 1)iOS开发基础-九宫格坐标(4)中 viewDidLoad 方法中的第21.22行对控件属性的设置能否拿到视图类 WJQAp ...

  7. iOS开发基础-九宫格坐标(4)

    对iOS开发基础-九宫格坐标(3)的代码进行进一步优化. 新建一个 UIView 的子类,并命名为 WJQAppView ,将 appxib.xib 中的 UIView 对象与新建的视图类进行关联. ...

  8. iOS开发基础-九宫格坐标(3)之Xib

    延续iOS开发基础-九宫格坐标(2)的内容,对其进行部分修改. 本部分采用 Xib 文件来创建用于显示图片的 UIView 对象. 一.简单介绍  Xib 和 storyboard 的比较: 1) X ...

  9. iOS开发基础-九宫格坐标(2)之模型

    在iOS开发基础-九宫格(1)中,属性变量 apps 是从plist文件中加载数据的,在 viewDidLoad 方法中的第20行.26行中,直接通过字典的键名来获取相应的信息,使得 ViewCont ...

随机推荐

  1. STM32 基于定时器的PWM发生器

    脉冲宽度调制(PWM),是英文"Pulse Width Modulation" 的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术.简单一点,就 ...

  2. Echarts 中国地图各个省市自治区自定义颜色

    前言 最近接了一个外包的项目,其中有个需求是这样的, 需要展示一个中国的统计地图,要求每个省市区都是不一样的颜色,必须特别区分开.以及隐藏南海部分. 看了Echats相关文档,发现有类似的demo,但 ...

  3. Nginx+tomcat配置集群负载均衡

    开发的应用采用F5负载均衡交换机,F5将请求转发给5台hp unix服务器,每台服务器有多个webserver实例,对外提供web服务和socket等接口服务.之初,曾有个小小的疑问为何不采用开源的a ...

  4. Socket网络编程详解

    一,socket的起源 socket一词的起源 在组网领域的首次使用是在1970年2月12日发布的文献IETF RFC33中发现的, 撰写者为Stephen Carr.Steve Crocker和Vi ...

  5. 使用redis做缓存

    redis常本用来作为缓存服务器.缓存的好处是减少服务器的压力,数据查询速度快.解决数据响应慢的问题. 添加缓存:只用redis的Hash数据类型添加缓存. 例如:需要在查询的业务功能中,添加缓存 1 ...

  6. Laravel中构造方法中不能写return!!!

    今天遇到的大坑 在laravel中 __construct 这个方法中不能写return 完全不能返回 而且还会向下执行具体原因不知道为什么解决办法!!!!用中间件来实现就可以了 Over!!!

  7. Oracle中SQL语句分类

    Oracle中SQL语句分类如下:1.DML语句 insert/delete/update/select/merge/explan plan/lock table2.DDL语句 create/atlt ...

  8. 用tensorflow迁移学习猫狗分类

    笔者这几天在跟着莫烦学习TensorFlow,正好到迁移学习(至于什么是迁移学习,看这篇),莫烦老师做的是预测猫和老虎尺寸大小的学习.作为一个有为的学生,笔者当然不能再预测猫啊狗啊的大小啦,正好之前正 ...

  9. JavaScript 流程语句知识脑图

  10. HDFS基本原理及数据存取实战

    ---------------------------------------------------------------------------------------------------- ...