一.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.
代码表示如下:
@property (nonatomic,strong) void(^myBlock)(NSString *);
说明:这里定义了一个无返回值,参数为NSString *的Block,Block的名字为myBlock,这就类比声明一个函数void test(int);——无返回值,参数为int,函数名为test.
如果是创建一个int返回值的block将上面的void改为int
且这里的Block类型为strong类型,关于Block的修辞策略后面再讲.
if (_myBlock) {
_myBlock(@"1234567");
NSLog(@"%@", str);
}
说明:这里的if是对Block先进行判断,作用是判断Block是否已经分配好内存,如果定义完成就执行,并传入了一个字符串参数
如果block有返回值,那么可以用一个值来接收它的返回值如int num = _myBlock(@“1234567”);
先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是对象.(因为它是对象,所以用%@格式打印可以看到它的内存分配区),文档描述第一句话如下:
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内部访问的是局部变量,那么就是值传递,否则就是指针传递
- 07 consistent gets、db block gets的简单精辟的理解
consistent gets.db block gets的简单精辟的理解 consistent gets:一致性读,为了保持读一致性而获取的块,其中可能包括undo block,也有包括非u ...
- block的传值简单示例仅供参考,大牛勿喷
#import "ViewController.h" typedef void(^sumBlock)(int s);//声明为一个类型; /** * 用声明的block类型 su ...
- block 的调用 简单代码
#import <Foundation/Foundation.h> #import "Button.h" typedef int (^MySum) (int, int) ...
- iOS-重回block小白之路
在我刚刚接触iOS开发的时候,是通过MJ老师讲的OC基础入门的,iOS圈的人应该基本都知道MJ大神吧,即便如此大神,讲解完block之后我依然感觉晕晕乎乎的,直到后来真正进公司做项目,依然感觉这是自己 ...
- cocos2dx游戏开发——别踩白块学习笔记(一)——Block类
一.Block类介绍 当然啦,Block类在这个游戏里就是必需品= =,因为整体都是由这个搞出来的,所以我们可以把游戏需要实现的功能都放在这里. 主要有下面这些功能(经典模式): 1.创建一个Bloc ...
- iOS中Block的基础用法
本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等.用过GCD就知道 ...
- UIView简单动画
UIView动态实现的效果有以下几种: 1.动态改变frame 2.动态改变color 3.动态改变alpha 4.动态改变bounds 首先,我们先看几种BasicView动画 #pragma ma ...
- Block 的基本用法
iOS中Block的基础用法 转载自简书 本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对 ...
- iOS之block
1. Block的声明和线程安全Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的,可以参考之前的文章(iOS: 非ARC ...
随机推荐
- Mysql分页处理(PageHelper)
第一次做分页处理(完全不知道分页处理到底要做成什么样?) 理解:其实就是前台页面通过传递不同的参数{1.查询的条件.2.查询页数(pageNum),3每页展现的条数(pageSize)},之后我们(只 ...
- 使用CXF开发JAX-WS类型的WebService
使用CXF记得要先加入CXF的jar包 方法1: Cxf编程实现: l 使用jaxwsServerFactoryBean发布 webservice服务端. 需要设置: jaxwsServerFacto ...
- 如何快速把 Vue 项目升级到 webpack3
由于 webpack3升级后,新增了 Scope Hositing(作用域提升) 功能,据说是对 js的性能提升很大.因此,我们做了一个测试对比,就是 webpack3和 webpack1/2 的性能 ...
- Spring MVC入门讲解
一.Springmvc是什么? Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想, 将web层进行职责解耦,基 ...
- unity调用c++ dll方法介绍
摘要 unity用的很普遍,现在很多代码还是用c++写的,需要用unity去调用c++的代码.这里介绍了一种unity调用c++ dll的方法,希望有所帮助. 我采用的软件是Visual Studio ...
- 【Beta阶段】第三次scrum meeting
Coding/OSChina 地址 1. 会议内容 学号 主要负责的方向 昨日任务 昨日任务完成进度 接下去要做 99 PM 打包上传团队代码 100% 查找适合的素材模块,和105一起把手势功能连接 ...
- 201521123080《Java程序设计》第3周学习总结
1. 本周学习总结 初学面向对象,会学习到很多碎片化的概念与知识.尝试学会使用思维导图将这些碎片化的概念.知识组织起来.请使用纸笔或者下面的工具画出本周学习到的知识点.截图或者拍照上传. 2. 书面作 ...
- 201521123051《Java程序设计》第十一周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. Java多线程同步的方法: (1)同步方法:即有synchronized关键字修饰的方法. 由于java的每个对象 ...
- 【化繁为简】非前端开发者的福音---CSS的预处理语言 Less&Sass
写在前面: 众所周知CSS 是一门非程序式语言,没有变量.函数.SCOPE(作用域),在前期的界面样式设计时,需要书写大量看似没有逻辑的代码,不方便维护及扩展,也不利于重复调用,尤其对于 ...
- JAVA设计模式:蝇量模式
声明:转载请说明来源:http://www.cnblogs.com/pony1223/p/7554686.html 一.引出蝇量模式 现在假设有一个项目,这个项目是为公园设计一个景观的部署,那么这个时 ...