一.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. Mysql分页处理(PageHelper)

    第一次做分页处理(完全不知道分页处理到底要做成什么样?) 理解:其实就是前台页面通过传递不同的参数{1.查询的条件.2.查询页数(pageNum),3每页展现的条数(pageSize)},之后我们(只 ...

  2. 使用CXF开发JAX-WS类型的WebService

    使用CXF记得要先加入CXF的jar包 方法1: Cxf编程实现: l 使用jaxwsServerFactoryBean发布 webservice服务端. 需要设置: jaxwsServerFacto ...

  3. 如何快速把 Vue 项目升级到 webpack3

    由于 webpack3升级后,新增了 Scope Hositing(作用域提升) 功能,据说是对 js的性能提升很大.因此,我们做了一个测试对比,就是 webpack3和 webpack1/2 的性能 ...

  4. Spring MVC入门讲解

    一.Springmvc是什么? Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想, 将web层进行职责解耦,基 ...

  5. unity调用c++ dll方法介绍

    摘要 unity用的很普遍,现在很多代码还是用c++写的,需要用unity去调用c++的代码.这里介绍了一种unity调用c++ dll的方法,希望有所帮助. 我采用的软件是Visual Studio ...

  6. 【Beta阶段】第三次scrum meeting

    Coding/OSChina 地址 1. 会议内容 学号 主要负责的方向 昨日任务 昨日任务完成进度 接下去要做 99 PM 打包上传团队代码 100% 查找适合的素材模块,和105一起把手势功能连接 ...

  7. 201521123080《Java程序设计》第3周学习总结

    1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传. 2. 书面作 ...

  8. 201521123051《Java程序设计》第十一周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. Java多线程同步的方法: (1)同步方法:即有synchronized关键字修饰的方法. 由于java的每个对象 ...

  9. 【化繁为简】非前端开发者的福音---CSS的预处理语言 Less&Sass

    写在前面:        众所周知CSS 是一门非程序式语言,没有变量.函数.SCOPE(作用域),在前期的界面样式设计时,需要书写大量看似没有逻辑的代码,不方便维护及扩展,也不利于重复调用,尤其对于 ...

  10. JAVA设计模式:蝇量模式

    声明:转载请说明来源:http://www.cnblogs.com/pony1223/p/7554686.html 一.引出蝇量模式 现在假设有一个项目,这个项目是为公园设计一个景观的部署,那么这个时 ...