iOS开发基础block的形式讲解
前几个星期,我利用通知写了一个仿京东选择地址的Demo(http://blog.csdn.net/hbblzjy/article/details/52212879),后来看过一篇文章说,尽量少用通知,因为通知容易占据手机内存,即使你进行了通知移除处理,也不太保险,所以今天再次谈谈Block的使用,之前也写过一篇文章(http://blog.csdn.net/hbblzjy/article/details/51108159)。
首先在阅读本文之前,请尝试写出一下问题:
- 声明一个Block,并调用它。
- 声明一个Block型的属性。
- 声明一个方法,接受一个Block型的参数,并写出调用时传入的Block实参。
- 实现一个Block的递归调用(Block调用自己)。
- 实现一个方法,将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的形式讲解的更多相关文章
- IOS开发基础知识碎片-导航
1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...
- iOS开发关于Block代码错误
本文永久地址为http://www.cnblogs.com/ChenYilong/p/4052362.html ,转载请注明出处. iOS开发关于Block代码错误 Incompatible bloc ...
- iOS开发——总结篇&IOS开发基础知识
IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...
- IOS开发基础环境搭建
一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包: ...
- iOS开发基础-九宫格坐标(6)
继续对iOS开发基础-九宫格坐标(5)中的代码进行优化. 优化思路:把字典转模型部分的数据处理操作也拿到模型类中去实现,即将 ViewController 类实现中 apps 方法搬到 WJQAppI ...
- iOS开发基础-九宫格坐标(5)
继续在iOS开发基础-九宫格坐标(4)的基础上进行优化. 一.改进思路 1)iOS开发基础-九宫格坐标(4)中 viewDidLoad 方法中的第21.22行对控件属性的设置能否拿到视图类 WJQAp ...
- iOS开发基础-九宫格坐标(4)
对iOS开发基础-九宫格坐标(3)的代码进行进一步优化. 新建一个 UIView 的子类,并命名为 WJQAppView ,将 appxib.xib 中的 UIView 对象与新建的视图类进行关联. ...
- iOS开发基础-九宫格坐标(3)之Xib
延续iOS开发基础-九宫格坐标(2)的内容,对其进行部分修改. 本部分采用 Xib 文件来创建用于显示图片的 UIView 对象. 一.简单介绍 Xib 和 storyboard 的比较: 1) X ...
- iOS开发基础-九宫格坐标(2)之模型
在iOS开发基础-九宫格(1)中,属性变量 apps 是从plist文件中加载数据的,在 viewDidLoad 方法中的第20行.26行中,直接通过字典的键名来获取相应的信息,使得 ViewCont ...
随机推荐
- html文本encode后,js获取参数失败的bug
html中的空格encodeURIComponent后变成%C2%A0,而js中的空格是'%20',二者无法匹配,所以要进行一次替换
- centos 7 安装nvidia显卡驱动
How to install Nvidia drivers in CentOS 7 - Tutorial : http://www.dedoimedo.com/computers/centos-7- ...
- ES6(Decorator(修饰器))
Decorator(修饰器) 1.基本概念 函数用来修改 类 的行为 1.Decorator 是一个函数 2.通过Decorator(修饰器)能修改 类 的行为(扩展 类 的功能)3.Decorato ...
- JavaScript 字符串(String)对象
String 对象用于处理已有的字符块. JavaScript 字符串 一个字符串用于存储一系列字符就像 "John Doe". 一个字符串可以使用单引号或双引号: 实例 var ...
- myeclipse中修改maven的默认仓库位置
1.本地需要安装Maven.这里假设安装在D:\Program Files\apache-maven-2.2.1 2.修改本地maven库的路径:在D:\Program Files\ap ...
- 监听RecyclerView滑动到末端
监听RecyclerView滑动到末端 效果图 实现 1. 添加滑动到末端的接口 package com.kongqw.recyclerviewdemo; /** * Created by kongq ...
- python模块collections中namedtuple()的理解
Python中存储系列数据,比较常见的数据类型有list,除此之外,还有tuple数据类型.相比与list,tuple中的元素不可修改,在映射中可以当键使用.tuple元组的item只能通过index ...
- 理解性能的奥秘——应用程序中慢,SSMS中快(2)——SQL Server如何编译存储过程
本文属于<理解性能的奥秘--应用程序中慢,SSMS中快>系列 接上文:理解性能的奥秘--应用程序中慢,SSMS中快(1)--简介 本文介绍SQL Server如何编译存储过程并使用计划缓存 ...
- 【SSH系列】---Hibernate的基本映射
开篇前言 在前面的博文中,小编分别介绍了[SSH系列]-- hibernate基本原理&&入门demo,通过这篇博文,小伙伴们对hibernate已经有了基本的了解,以及h ...
- SQL基本函数
字符型函数 函数名称 描述 LOWER 将特定的字符串转化为小写,只影响字母字符串. UPPER 将整个字符串转换成大写,只影响字母字符串. INITCAP 将字符串中每一个单词的第一个字母转换为大写 ...