IOS进阶-理解OC中block、闭包(一)

无论开发中还是面试中,都会面临对于block使用方面的理解。而约定成俗的使用让我们知其然而不知其所以然。现参考多方资料总结对于block的多层次理解。

一、理论

什么是闭包

计算机语言中、“闭包(Closure)是由函数和与其相关的引用环境组合而成的实体.” block就是OC对闭包的实现.,Block是iOS4.0+ 和Mac OS X 10.6+ 引进的对C语言的扩展.

将“函数、函数指针、闭包”三者对比起来理解,能加深对闭包的理解;

函数:具有特定功能的代码块;

函数指针:指向函数的指针;

闭包:除具备“函数和函数指针”的所有功能外, 还包括声明它的上下文(如作用域内的自由变量等).

闭包的用途

1、“惰性求值”特性可用作定义控制语句;

2、多函数使用同一个环境;

3、实现对象系统.

通常来说,block都是一些简短代码片段的封装,适用作工作单元,通常用来做并发任务、遍历、以及回调。

闭包的实现

“典型实现方式是定义一个特殊的数据结构,保存了函数地址指针与闭包创建时的函数的词法环境(also lexical closures or function closures)。”

Block简介

1、block是将函数及其执行上下文封装起来的一个对象。

2、在block实现的内部,有很多变量,因为block也是一个对象。

3、其中包含了诸如isa指针,imp指针等对象变量,还有储存其截获变量的对象等。


定义和使用

block根据有无参数和有无返回值有以下几种简单使用方式

block是一种数据类型,可以使一段代码块变成一个变量,格式和函数很像. 

 1,无参无返回: void (^myBlock)() = ^(){  ...... };(无参的话前面小括号可以省略,后面分号不能少).

 2,有参无返回: void (^myBlock)(int,int) = ^(int a, int b){ .......};(有参数的话,'='号后面的形参名不能省).

 3,无参有返回: int (^myBlock)() = ^{.......return....};

 4,有参有返回:int (^myBlock)(int , int) = ^(int a ,int b){  ....return a+b;}; 

 不同于函数的是block可以在内部访问外部的变量,但是不能给外部变量重新赋值,因为在内部使用的外部变量是copy的新的外部变量,内存位置不一样. 

 在block内部也可以定义和外部同名的变量,这样就会屏蔽外部变量的作用域,内部无法使用外部变量. 

 在默认的情况下,内部不能修改外部变量.当给外部的局部变量加上__Block修饰词,则内部可以改变该变量.


block的种类

Objective-C语言中,一共有3种类型的block:

1、_NSConcreteGlobalBlock 保存在text段的全局的静态block,不会访问任何外部变量。

2、_NSConcreteStackBlock 保存在栈中的block,当函数返回时会被销毁。

3、_NSConcreteMallocBlock 保存在堆中的block,当引用计数为0时会被销毁。

以下说明几点需要注意的:

1、NSConcreteGlobalBlock 是全局静态block,结构体存储在数据区。

2、常见的是有捕获外部变量的_NSConcreteStackBlock,需要注意的是如果这种类型的block 定义在函数内部,当函数执行完毕,退栈的时候会将该block结构体所占的内存空间释放掉,这样再引用的话会报错。

3、_NSConcreteMallocBlock 通常不会在源码中直接出现,OC ARC下会对_NSConcreteStackBlock 进行优化,将其copy到堆上,转换成_NSConcreteMallocBlock,所以无特殊处理,OC中将只会有1,3两种类型block

4、_NSConcreteStackBlock捕获的局部变量,如不加_block修饰符,将会把变量copy一份到其结构体中,所以才会在内部修改不影响外部变量,加_block修饰之后,结构体中会添加一个__Block_byref_i_0 的结构体,且复制的是变量地址,达到可以修改外部变量的效果 


block的使用注意事项(面试常问情况)

在block内直接调用类的实例变量会使self(类的实例)引用计数加1, 这样可能会引起循环引用问题(可以用__weak或local-var处理);

使用null的block程序会crash. 使用前判断一下:if(blockVar) {//do something…};

在多线程环境下(block中的weakSelf有可能被析构的情况下),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被析构。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,313评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,369评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,916评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,333评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,425评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,481评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,491评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,268评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,719评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,004评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,179评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,832评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,510评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,153评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,402评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,045评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,071评论 2 352

推荐阅读更多精彩内容

  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 3,760评论 0 23
  • iOS开发---Block详解 Block的基础 什么是Blocks? 用一句话来描述:带有自动变量的匿名函数(是...
    祀梦_阅读 996评论 0 6
  • 1 Block机制 (Very Good) Block技巧与底层解析 http://www.jianshu.com...
    Kevin_Junbaozi阅读 4,042评论 3 48
  • 操作系统中的栈和堆 注:这里所说的堆和栈与数据结构中的堆和栈不是一回事。 栈区(stack):由系统自动分配,一般...
    拾丨玖阅读 626评论 0 1
  • block是C语言级别的语法和运行时特性,应用到Objective-C中可以增强函数功能。在合适场景中灵活应用bl...
    点融黑帮阅读 1,019评论 2 6