2018-03-21

从OC—Block到Swift—Closure

写在前面

阅读别人的代码,特别是一些被广泛认可的开源项目的源码,是快速提升自己能力的重要途径。由于个人编程风格的问题,有的大神写的代码就比较晦涩难懂,而且跳跃性很强,经常以跟不上ta的思路而宣告GG。对于我自己来说,我是比较不喜欢阅读Block/Closure特别多的代码的,用着很舒心,读着很糟心。。。
应该有很多(?)和我一样被无数Block或者闭包导致阅读过程中出现不安感的同学,在重新查阅了一些之前的笔记和大神们的资料后,斗胆在这里做一个总结,希望能为读到这里的同学们提供些许的念头通达。
篇幅略长,尽量不赘述,前面是block,中间是closure,最后一些tips,请选择性观看。

利益相关

本文原创,其中有引用别人帖子/博客/回答/etc, 参考内容较多不一一列举,如果您发现有侵权行为或者在意没有注明引用,请@龙傲天联系我等我看到邮件再说 我会在第一时间更正。
时刻保持您的谨慎与怀疑,因为我说的并不是真理。
本文不保留任何权益,开心就好。

概述

Block(代码块)是苹果在iOS4开始引入的对C语言的扩展,是一种特殊的数据类型。它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回调。
Closure(闭包)是Swift在吸收众家之长的基础上的特性之一,是自包含的功能代码块,可以在代码中使用或者用来作为参数传值。

这里做个简单介绍:

Block的功能:

  1. 定义变量
  2. 作为参数
  3. 作为返回值
  4. 保存一段代码,在需要的时候调用

Closure的功能:

Swift中的闭包使用情况远比Objective-C中的多,以至于闭包就是Swift的基本特性之一,和String/Array是一样的使用频率。
Closure的功能大于等于Block的功能,并有更多的优化。

::注:::Closure != Block,即闭包不是Block的Swift版。

block的声明和赋值

相信很多人(也许只有我)很难在不参考任何资料或者在编辑器的支持下正确的定义一个block,这时推荐Xcode自带的代码块来声明它:

// block声明
返回值类型(^block名称)(参数列表)
// block赋值
Block变量 = ^(参数列表){函数体};

// block声明同时赋值
返回值类型(^block名称)(参数类型) = ^(参数列表) {
    内部的实现方法 / 参数处理 / 想要在别处调用而保存的代码
    };

光说不练假把式,现在我们来写一个block让它来”HelloWorld”:

// 可以新建一个工程,然后在 viewDidLoad 中进行简单测试,开始吧

// 声明一个无返回值,参数为两个字符串对象,叫做myBlock的Block
void(^myBlock)(NSString *a, NSString *b);
// 形参变量名称可以省略,只留有变量类型即可(这个不是必要操作,但是要知道可以这样写)
void(^myBlock)(NSString *, NSString *);

// 给myBlock赋值
myBlock = ^(NSString *a, NSString *b) {
        NSLog(@"%@ %@",a,b);
    };

// 调用myBlock
myBlock(@"hello",@"world");

// 控制台输出结果
"hello world"

更为复杂的block也无非就是在这个基础上改变参数列表,增加函数体内的方法。Is it easy?

注: block的声明与赋值只是保存了一段代码段,必须调用才能执行内部代码

对于block的底层原理在这里不做探究, 因为其实我也没研究懂 因为本文重点是面向实际使用过程的,有兴趣的同学可以自行查询。
传送门: block源码下载
唐巧—谈Objective-C block的实现

block特性

  • block被Objective-C看成是对象来处理
  • block对于外部变量默认是只读属性
  • block的代码是内联的,效率高于函数调用
  • block的声明与赋值只是保存了一段代码段,必须调用才能执行内部代码

使用typedef定义Block类型

在实际使用Block的过程中,我们可能需要重复地声明多个相同返回值,相同参数列表的Block变量,如果总是重复地编写一长串代码来声明变量会非常繁琐,所以我们可以使用typedef来定义Block类型(还记得之前我们的myBlock吗,现在把它定义成一个类型):

    // 将下面这个接受两个NSString参数,返回为空的block类型定义为名字为MyBlock的类型
    typedef void(^MyBlock)(NSString *, NSString *);
    // 使用的时候指定要使用MyBlock类型的,新建一个该类型的block对象,并定义它的工作内容
    MyBlock myNewBlock = ^(NSString *a, NSString *b) {
        NSLog(@"%@ %@",a,b);
    };
    // 让block开始工作
    myNewBlock(@"hello",@"myNewBlock");
      // 输出结果
      "hello myNewBlock"

      // 再次创建一个MyBlock类型的对象,并给它定义与之前不同的工作内容
    MyBlock anotherBlock = ^(NSString *str1, NSString *str2) {
        NSLog(@"only print str2: %@",str2);
    };
    // 让block开始工作
    anotherBlock(@"hello",@"world");
      // 输出结果
    "only print str2: world"

Block作为函数参数

之前的情形是直接调用block,让它执行自己内部封装的方法,更多的时候是将block当做参数传递并进行操作的,继续我们的例子:

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

推荐阅读更多精彩内容