Block简介:

      ios4.0系统已开始支持block,在编程过程中,blocks被Obj-C看成是对象,它封装了一段代码,这段代码可以在任何时候执行。Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。它和传统的函数指针很类似,但是有区别:blocks是inline的,并且它对局部变量是只读的。

1、block的定义

       // 声明和实现写在一起,就像变量的声明实现 int a = 10;
int (^aBlock)(int, int) = ^(int num1, int num2) {    return num1 * num2; };
// 声明和实现分开,就像变量先声明后实现 int a;a = 10;
int (^cBlock)(int,int);
cBlock = ^(int num1,int num2)
{
return num1 * num2;
};

 其中,定义了一个名字为aBlock的blocks对象,并携带了相关信息:

  1、aBlock 有两个形式参数,分别为int类型;

  2、aBlock 的返回值为int 类型;

  3、等式右边就是blocks的具体实现;

  4、^ 带边blocks声明和实现的标示(关键字);

当然,你可以定义其他形式的block。e.g:无返回值,无形式参数等;

         void (^bBlock)() = ^()
{
int a = ;
printf(num = %d,a);
};

2、blocks 访问权限

  blocks可以访问局部变量,但是不能修改。

         int a = ;
int (^dBlock)(int) = ^(int num)
{
a++;//not work!
return num * a;
};

3、block的调用

  block调用就像调用函数一样。

int c = aBlock(,);

bBlock();

4、block 应用

  假设我们熟悉代理递值的话,对代理我们可能又爱有恨!我们先建立模型A页面 push B页面,如果把A页面的值传递到B页面,属性和单例传值可以搞定!但是如果Pop过程中把B页面的值传递到A页面,那就可以用单例或者代理了!说到代理,我们要先声明协议,创建代理,很是麻烦。常常我们传递一个数值需要在两个页面间写很多代码,这些代码改变页面的整体顺序,可读性也打了折扣。所以,此时,block是一种优化方案!

5、 block的内存管理

block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。比如下面的例子。 我在view did load中创建了一个block:

- (void)viewDidLoad
{
[superviewDidLoad]; int number = ;
_block = ^(){
NSLog(@number %d, number);
};
}

并且在一个按钮的事件中调用了这个block:

- (IBAction)testDidClick:(id)sender {
_block();
}

此时我按了按钮之后就会导致程序崩溃,解决这个问题的方法就是在创建完block的时候需要调用copy的方法。copy会把block从栈上移动到堆上,那么就可以在其他地方使用这个block了~ 修改代码如下:

_block = ^(){
NSLog(@number %d, number);
};
_block = [_blockcopy];

同理,特别需要注意的地方就是在把block放到集合类当中去的时候,如果直接把生成的block放入到集合类中,是无法在其他地方使用block,必须要对block进行copy。不过代码看上去相对奇怪一些:

[array addObject:[[^{
NSLog(@hello!);
} copy] autorelease]];

6、循环引用
      对于非ARC下, 为了防止循环引用, 我们使用__block来修饰在Block中使用的对象:
      对于ARC下, 为了防止循环引用, 我们使用__weak来修饰在Block中使用的对象。原理就是:ARC中,Block中如果引用了__strong修饰符的自动变量,则相当于Block对该变量的引用计数+1。
这一点其实是在第一点的一个小的衍生。当在block内部使用成员变量的时候,比如

@interface ViewController : UIViewController
{
NSString *_string;
}
@end

在block创建中:

_block = ^(){
NSLog(@string %@, _string);
};

这里的_string相当于是self->_string;那么block是会对内部的对象进行一次retain。也就是说,self会被retain一次。当self释放的时候,需要block释放后才会对self进行释放,但是block的释放又需要等self的dealloc中才会释放。如此一来变形成了循环引用,导致内存泄露。
修改方案是新建一个__block scope的局部变量,并把self赋值给它,而在block内部则使用这个局部变量来进行取值。因为__block标记的变量是不会被自动retain的。

__block ViewController *controller = self;
_block = ^(){
NSLog(@string %@, controller->_string);
};

原文来自:http://www.2cto.com/kf/201504/388349.html

IOS开发Block详细用法的更多相关文章

  1. ios Block详细用法

    ios Block详细用法 ios4.0系统已开始支持block,在编程过程中,blocks被Obj-C看成是对象,它封装了一段代码,这段代码可以在任何时候执行.Blocks可以作为函数参数或者函数的 ...

  2. iOS开发--Block

    iOS开发--Block 1.什么是Block,block 的作用 ui开发和网络常见功能实现回调,按钮的事件处理方法是回调方法以及网络下载后的回调处理 (1)按钮 target-action   一 ...

  3. iOS开发——Block详解

    iOS开发--Block详解 1. Block是什么 代码块 匿名函数 闭包--能够读取其他函数内部变量的函数 函数变量 实现基于指针和函数指针 实现回调的机制 Block是一个非常有特色的语法,它可 ...

  4. ios开发 block语句块

    ios开发 block语句块 1.block 理解为匿名函数 2.block变量的定义 //定义block变量,^表示定义block //技巧:函数名左右加括号,在函数名前面在加^ void (^bl ...

  5. iOS中block的用法 以及和函数用法的区别

    ios中block的用法和函数的用法大致相同 但是block的用法的灵活性更高: 不带参数的block: void ^(MyBlock)() = ^{}; 调用的时候  MyBlock(); 带参数的 ...

  6. iOS中Block的用法,举例,解析与底层原理(这可能是最详细的Block解析)

    1. 前言 Block:带有自动变量(局部变量)的匿名函数.它是C语言的扩充功能.之所以是拓展,是因为C语言不允许存在这样匿名函数. 1.1 匿名函数 匿名函数是指不带函数名称函数.C语言中,函数是怎 ...

  7. iOS开发-Block回调

    关于Block之前有一篇文章已经写过一篇文章Object-C-代码块Block回顾,不过写的比较浅显,不能体现出Block在实际开发中的重要性,关于Block的基础知识,可以参考之前的博客.在实际开发 ...

  8. ios delegate, block, NSNotification用法

    ios中实现callback可以通过两种方法,委托和NSNotification 委托的话是一对一的关系,例如一个UIViewController里有一个tableView, 将该viewContro ...

  9. iOS开发Block的使用

    Block 是从 iOS4引入的,在日常开发中,会经常用到Block.特别是在多线程中,Block的用处更广泛.而且,Block不仅可以接收参数,其本身也可以作为参数,因此,Block的功能非常强大. ...

随机推荐

  1. [BZOJ1576]安全路经Travel

    题目大意:从1号点出发,到每个点的最短路的最后一条边不能被访问,求此时1号点到其他点的最短路 建立最短路树,对于一条非树边,把它加进去会形成一个环和一条链,如图: 即红色和蓝色路径构成的图,它的长度为 ...

  2. Swift学习笔记 - OC中关于NSClassFromString获取不到Swift类的解决方案

    在OC和Swift混编的过程中发现在OC中通过NSClassFromString获取不到Swift中的类,调研了一下发现问题所在,下面是我的解决方案: 问题的发现过程 UIViewController ...

  3. Java ArrayList在foreach中remove的问题分析

    目录 iterator itr.hasNext 和 itr.next 实现 倒数第二个元素的特殊 如何避坑 都说ArrayList在用foreach循环的时候,不能add元素,也不能remove元素, ...

  4. Linux升级内核总结

    Linux内核升级总结. 一.编译内核步骤 1.#uname –r 确定系统的原内核版本,然后下载较新版本的Linux内核源码包 http://www.kernel.org/pub/linux/ker ...

  5. Docker Mysql主主同步配置搭建Demo

    主主同步配置和主从配置很相似,仅需稍做修改就可以了,对主从配置有疑问可以查看 上一篇文章. 进行Docker操作前,先建立目录,我的路径是d:/docker/mysql,目录结构如下: --mysql ...

  6. Zookeeper Zkclient客户端

    Zkclient是对Zookeeper的原生API进行了包装,实现了超时重连.Watcher反复注册等功能,它可以实现递归创建,删除节点,但是zkClient不能递归给节点赋值. 主要的api如下: ...

  7. 微信小程序:scroll-view的bug

    flex:1并不能使scroll-view的高度固定,需要添加高度height:1rpx(数值大于0)就行

  8. 【三小时学会Kubernetes!(零) 】系统结构及相关示例微服务介绍

    写在前面 牢牢占据容器技术统治地位的 Kubernetes,其重要性想必不言而喻,我保证本文是最详尽的 Kubernetes 技术文档,从我在后台排版了这么漫长的时间就能看出来.废话不多说 — — 以 ...

  9. Spring MVC:控制器类名称处理映射

    控制器类名称处理映射的好好处是: 如果项目是hello,WelcomeController是控制器,那么访问地址是: http://localhost:8080/hello/welcome http: ...

  10. html合并单元格

    在合并的首位置加上colspan或者rowspan属性即可 code: <html>   <body>   <h4>横跨两列的单元格:</h4> < ...