一.Block简单的使用
1.block当作参数来传递
如下定义一个没有返回值无参数的block,并把它作为参数,让系统调用,注意:这里是系统在调用,不是我们调用
那么为什么需要把block当作参数去使用呢?
这就引出了block这个时候的使用场景:当自己封装一个类的时候,有些事情由外部决定,但什么时候做由内部决定,(即内部决定执行时间,外部传入具体做些什么)——这个时候就可以使用block来作为参数
2.block当作返回值来使用
如下代码,test为方法名,void(^)()这就是block的类型,这样就可以这样使用,其中的的self.test是相当于属性的get方法,后面再加一个()就相当于执行block.
同时时还可以将这个block给相同类型的bock赋值.如下代码所示.
所以myBlock后加一个小括号就是执行,这样就能理解为什么上面self.test加一个小括号就是执行.——这让我联想到swift里执行函数都是点点点,并且加上()就是创建对象执行函数等等,原来都是这么的类似....
block当返回值使用思想:链式编程,把方法调用通过语法链接起来,可读性非常好
下面简单来演示一下用Block来进行链式编程
创建一个类继承NSObject命名为AddTool,即到时我们要用它来进行链式累加,它的.h文件里如下
它的.m文件如下:
然后在ViewController类里进行调用如下
运行起来,打印结果为,OK完成!
 
二.Block逆传值的使用
     Block可以用于控制器界面间逆向传值.使用方法是这样:控制器B传值给控制器A, 那么要在控制器B中的头文件.h声明一个Block属性, 并且在控制器B的.m文件中执行这个Block.
代码表示如下:
    • 在B的头文件中
@property (nonatomic,strong) void(^myBlock)(NSString *);
     说明:这里定义了一个无返回值,参数为NSString *的Block,Block的名字为myBlock,这就类比声明一个函数void test(int);——无返回值,参数为int,函数名为test.
     如果是创建一个int返回值的block将上面的void改为int
     且这里的Block类型为strong类型,关于Block的修辞策略后面再讲.
    • 在B的.m文件中这样使用
    if (_myBlock) {
        _myBlock(@"1234567");
        NSLog(@"%@", str);
    }
     说明:这里的if是对Block先进行判断,作用是判断Block是否已经分配好内存,如果定义完成就执行,并传入了一个字符串参数
     如果block有返回值,那么可以用一个值来接收它的返回值如int num = _myBlock(@“1234567”);
    • 在A的.m文件中
先importB的头文件,再创建一个B的具体对象如下为myVC,然后
    myViewController *myVC = segue.destinationViewController;
    myVC.myBlock = ^(NSString *str){
        NSLog(@"%@", str);
    };
     说明:如果block有返回值,那需要在Block内部加上一句return才行.如return 10;这样myBlock就有了值,从而B中的num也就有了值.即这个有值的过程是先内部的block有值然后执行完外部才有值.
 
三.Block的循环引用问题
1.简单循环引用
循环引用的描述:就是当对象不想使用时本应释放,但由于循环强引用,谁也释放不了谁造成内存泄露.
 
Block发生循环引用的场合:ARC中Block为strong或copy属性,在Block内部使用了当前类的self属性,同时这个类包含了别一个类的Block属性.
 
举例:还是上面的传值的例子,现假如在A的.m文件的block里使用了self.view.backgroundColor = [UIColor redColor];现在这些对象之间的引用关系如下图所示:
因此这样就就造成了循环引用.
 
Block内循环引用的解决:
在如下的例子,可以在Block外加上这样一句(如果将typeof用于表达式,则该表达式不会执行。只会得到该表达式的类型。)
__weak typeof(self) weakSelf = self;
或者这样也可以
__weak ViewController *weakSelf = self;
2.复杂循环引用
这个还没遇到过,只是看到有这样用过.....这个后面有时间再分析!
 
四.Block的内存分析(ARC与非ARC下的验证)
如何验证arc还是非arc,一点点回顾
1.arc中无法调用retain和release,并且dealloc方法不能调用super dealloc.非ARC中super dealloc写在最后面
2.项目 -> build settings -> ARC
ARC的set方法如下,与上次值不相等,就释放旧值,retain新值..所以我们在ARC应尽量用self.这种方式去调用set方法,而不要直接使用下划线,因为会内存泄露.
非ARC中没有weak,没有strong,只有对应的assign和retain
strong与copy:因为上面这里字符串用到了copy,而且上面代码也是ARC下copy内部做的事,也就是它会release旧值,将新字符串name重新copy一份赋值给旧_name.这样当我们改变_name时,不会影响到name.(ps:arc下一般如果不会改变的字符串就尽量用strong,因为省得copy一份出来,相比而言copy更耗性能,对于ARC下使用Block也是如此,不需要copy就用strong就好)
 
内存5大区
内存分为5大区:堆, 栈, 方法区, 静态区(全局区), 常量区
 ps: 全局区和静态区其实是一样的,从内存上来看,全局变量和静态变量都是保存在静态存储区,生命期和程序一样,都是在静态数据区分配内存.在程序结束后回收内存.
  它们之间作用域有所不同,全局变量的作用域是整个项目,静态全局变量是当前程序文件,静态局部变量是当前函数体内.
堆:手动管理内存     栈:代码块一过,系统自动回收对应内存区
 
 首先来了解一下Block,苹果官方文档Block是对象.(因为它是对象,所以用%@格式打印可以看到它的内存分配区),文档描述第一句话如下:

非ARC下:

1.全局区的情况:如下定义一个Block,并将它使用, 它的打印结果为,global表示全局区.全局区表示到处都可以使用.(ps:假如block内部访问static修辞的外部局变量,那么它也是在全局区,关于静态区与全局刚刚上面已经解释过)
2.栈区:如下当Block内访问一个外面的局部变量a,它的打印结果为,stack表示栈区
总结如下:Block的内存分配与它内部访问的变量有关,如果访问的是全局变量,那Block会在全局区;  如果访问局部变量,那Block会分配到栈区.(什么也不访问默认在全局区)
 
3.堆区:使用copy进行强引用时block会copy一份到堆区
在非ARC环境下用retain修辞Block会有黄色警告,如下图,警告提示最好使用copy
假如现在就用retain,并且在block内访问了一个局部变量a(这个a就写在Block的上面),代码如下,这时发现一运行程序就漰了.(坏内存访问,报错会出现在使用self.Block的地方)
这一点总结:在非ARC下不能用retain引用block,因为这样不会把block放在堆里,它会在栈区,所以代码区一出括号就会销毁,于是会报错.只要使用copy就可以把block放到堆里面.这样block就不会销毁.——所以说block要用copy都是老程序员说的,因为那时没有ARC.
 
ARC下:
1.全局区:还是如下代码,默认Block还是放在全局区,没访问外部变量就都是在全局区,与是否ARC无关
2.堆:访问一个外部局部变量或对象时,代码如下,它的打印结果,这个malloc分配的内存是表示在堆上.(这有点像ARC下默认一个对象就是强引用,好处是不会一创建就销毁.)
 
五.Block的内变量的传递与改变
看下面代码,这个很简单,block打印出来肯定是10
 
值传递
再看如下代码,这个打印出来是5, 虽然block()执行之前a = 10,但,因为a = 5之后就立即被传递进了block,只是还没有执行而已,即内存已配好.而且这时的block是值传递,这时外面更改无法改变里面的值.(如果是指针传递则可以)
 
指针传递
那么再看如下代码,这个打印结果会是10,原因:只要局部变量生命周期是整个app运行都在,那么就是指针传递
这里加static后,生命周期就与整个程序同存亡了.与全局区一样(这一点上面Block内存分析时分析过了)
 
下在情况也是指针传递,所以打印出来也会是10
 
block变量传递总结:如果在block内部访问的是局部变量,那么就是值传递,否则就是指针传递

Block使用的简单总结的更多相关文章

  1. 07 consistent gets、db block gets的简单精辟的理解

    consistent gets.db block gets的简单精辟的理解     consistent gets:一致性读,为了保持读一致性而获取的块,其中可能包括undo block,也有包括非u ...

  2. block的传值简单示例仅供参考,大牛勿喷

    #import "ViewController.h" typedef void(^sumBlock)(int s);//声明为一个类型; /** *  用声明的block类型 su ...

  3. block 的调用 简单代码

    #import <Foundation/Foundation.h> #import "Button.h" typedef int (^MySum) (int, int) ...

  4. iOS-重回block小白之路

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

  5. cocos2dx游戏开发——别踩白块学习笔记(一)——Block类

    一.Block类介绍 当然啦,Block类在这个游戏里就是必需品= =,因为整体都是由这个搞出来的,所以我们可以把游戏需要实现的功能都放在这里. 主要有下面这些功能(经典模式): 1.创建一个Bloc ...

  6. iOS中Block的基础用法

    本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等.用过GCD就知道 ...

  7. UIView简单动画

    UIView动态实现的效果有以下几种: 1.动态改变frame 2.动态改变color 3.动态改变alpha 4.动态改变bounds 首先,我们先看几种BasicView动画 #pragma ma ...

  8. Block 的基本用法

    iOS中Block的基础用法 转载自简书 本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对 ...

  9. iOS之block

    1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...

随机推荐

  1. jQuery EasyUI弹出确认对话框(确认操作中.....)

    因为毕业设计的原因,在初期设计系统的时候没有考虑功能的正确性,所以很多的功能都没有加验证和确认的操作,给人在操作方面上有一些不好的感觉(可能失误点击后,数据就别删除,或者增加了),所以在网上找了一些资 ...

  2. jsp fmt标签详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt326 JSTL标签提供了对国际化(I18N)的支持,它可以根据发出请求的客户 ...

  3. 第1阶段——uboot分析之启动函数bootm命令 (9)

    本节主要学习: 详细分析UBOOT中"bootcmd=nand read.jffs2 0x30007FC0 kernel;bootm 0x30007FC0"中怎么实现bootm命令 ...

  4. 第1阶段——uboot分析之查找命令run_command函数和命令定义过程(6)

    本节主要学习,run_command函数命令查找过程,命令生成过程 1.run_command函数命令查找过程分析:在u-boot界面中(main_loop();位于u-boot-1.1.6/comm ...

  5. 用shell批量编码转换

    -------------------------------------文件内容转换:iconv-------------------------------------- 通常,从其他平台拷贝过来 ...

  6. Node.js中Async详解:流程控制

    安装 npm install async --save 地址 https://github.com/caolan/async Async的内容主要分为三部分 流程控制: 简化九种常见的流程的处理 集合 ...

  7. 老板让我们去陪睡!-It高管的焦虑

    老板是我非常敬重的前领导之一,他的一些管理风格,也影响了后来我对技术团队的管理.就是这样一个非常令人尊敬的领导,为什么会有这么过分的要求,请允许我先卖个关子,接下来就会知道. 理想企业 什么是程序员理 ...

  8. [2017BUAA软工助教]评论汇总

    一 邹欣 周筠 飞龙 二 学校 课程 教师 助教1 助教2 助教3 福州 软件工程1715K 柯逍 谢涛 软件工程1715Z 张栋 刘乾 汪培侨 软件工程1715W 汪璟玢 曾逸群 卞倩虹 李娟 集美 ...

  9. 学习目标或者作业的制定(SMART原则)

    以下文字摘自邹欣老师的博客 很高兴看到学生们都写了自己的目标: http://www.cnblogs.com/deng201421123059/p/6435346.html 不得不说,有些同学的目标太 ...

  10. Ubuntu下PHP MySQL环境搭建-upcoming-ChinaUnix博客

    编程语言选择php5 , web服务器选择Apache2 ,后台数据库选择MySQL首先安装编译工具, 打开终端 sudo apt-get install build-essential autoco ...