美文网首页iOSKotlin Three@IT·互联网
我与 Kotlin 的爱恨情仇之浅谈 block

我与 Kotlin 的爱恨情仇之浅谈 block

作者: IMSk | 来源:发表于2017-05-22 23:30 被阅读1008次

前言

     hi, 是的,你没看错,没迷路,这里是 Kotlin  ,不是 Objective-C,别怕接下来跟我一起认识认识这个 block 的前世今生。前方高能,请您带上耳机,戴上眼镜。

block是什么?

先来看看 Kotlin 代码长什么样子:

body has a function type:() -> T

    其中 body 就是一个 block, () -> T 是一个 函数块( 函数签名 )。block 可以当做参数传入, 也可以当做返回值返回。在这里我就沿用我之前写 Objective-C 的习惯,暂且称作他为 闭包。

 引用下block概念定义: 

In programming languages, a closure is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables (also called free variables or upvalues) of that function.

我爱 block

    再来对比一下 Objective-C 里的 block:

double (^multiplyTwoValues)(double, double);

OC中的block例子

    如果之前没有写过OC,那么我想第一反应只能无奈的说一句:不觉明历。回头来看看,还是 Kotlin 更加亲切一些,直接() -> T ,“{}”, 随便怎么玩,详细用法看官网吧《Higher-Order Functions and Lambdas》。

    为什么爱上 block, 举个简单例子: 我们经常要处理一个异步请求,等数据返回的时候,回调给调用方,如果是用 Java 来写,可能要用到接口(callback)来实现了的。那么在 Kotlin 里怎么办呢?

 声明:

block声明

调用:

block调用方

      看到了么?不用在像以前那样还要单独去写一个 callback 的 interface的类了,是不是很简洁。

我不爱 block

       当然很大一部分原因是因为当年被 OC 中的 block 折磨的心累,写法让人难受不说,OC先天的冗长代码实在是累,如果是个新手,还经常内存泄露,折磨的死去活来的。这里提一下,block是一个闭包,开发过程中,切记由于闭包是可以访问上文数据,处理不当就会导致内存泄露哦。

      当然还有另外一方面的原因,就是声明多参数的时候,比较难受,OC实在是不想在提了的,事实上 Kotlin 还算可以接受的,比如:

Kotlin 中 block 多参数声明 Kotlin 中 block 多参数调用

写在最后

      Kotlin 中 block 随处可见 “{ ..do somethings.}”,所以咱必须得掌握它,比如结合提供的列表操作的语法糖:

strings.filter{it.length==5}.sortBy{it}.map{it.toUpperCase()}

比如在 Android 中写一个延迟的 Runnable:

postDelayed({

//do somethings block

},300)

      block 让代码写起来更加方便,更加灵活(比如尾闭包等),函数式编程三板斧离不开它,但 block 同时带来的弊端也是有的,比如可读性差/内存管理头疼等。但个人愚见,利大于弊,虽然一直褒贬不一,饱受争议的一个神奇的东西。既然提到 block 那么当然离不开另外一个神奇的东西 typedef 。还好最新的 Kotlin 中已经有了 一个类似的东西 Type aliases .(Type aliases (since 1.1) - Kotlin Programming Language) . 如果大家感兴趣的话,那我下一章来谈谈这个 block 离不开的小情人吧。

     BTW  上面文中提到,block 都有可能会出现内存泄露问题,无论还是 OC 是 Kotlin,当然我并没有提到如何解决,留给你第一个想象空间,那么第二个想象空间就是,既然有内存泄露,那么 block 的实现原理又是什么呢? 跟匿名内部类有什么区别呢?


如果您愿意听我聊技术,可以关注我的个人公众号SKMacTalk:

SKMacTalk

相关文章

网友评论

  • bb779ca5a5e6:楼主高产似母猪:stuck_out_tongue_winking_eye:
    IMSk:@Conquer_ec32 评论你最帅:yum:
  • 依然fantac:1. block的原理是编译器生成的匿名内部类(我是通过反编译发现的哈哈)
    2. 基于1的认识,block内存泄露的担忧也就是匿名内部类导致的内存泄露的担忧。 一般来说,block对象被及时释放,就不会存在内存泄露
    依然fantac:匿名内部类会含有外部类引用,如果这个外部类加上弱引用是不是可以解决内存泄露问题。如果可以,为啥编辑器没这么做呢
    IMSk:修正一下,刚看了下 package kotlin.jvm.functions ,这里面有20多个interface。当Kotlin声明的block 在Java中调用的时候 就会被转换这里的new Function 等于是Java里面的interface。 所以在Kotlin里面的block最终在Android上表现的是编译器帮你做了这件事情罢了的。
    IMSk: 小伙子你很好。第一点我在写Android应用时候 确实发现是这样子的,所以啊 我上一篇文章最后总结里面就提到了的。语言仅仅是个工具,越多的语法糖,只是帮你省去了很多繁琐的编码过程,但很多时候本质上性能瓶颈并不一定就能把你解决掉。
    再来谈谈内存泄露,那么就要涉及到内存管理上的问题,每个平台都有自己的管理方式,那么如果使用了ARC(自动回收机制),由于block是可以访问到上下文数据,所以会导致引用计数变化,从而导致无法析构回收. 那么解决问题大概都是一样的,从引用上做工作,比如弱引用等。
  • 依然fantac:高产的SK, 坐等更新
    IMSk:@依然fantac 帅气的fantac
    依然fantac:@IMSk 已赏,拿去撸
    IMSk:@依然fantac 您的打赏,我才能去买书读书,才能写文章。
  • SwiftFun:高产,排版有进步 :+1: :clap:
    IMSk:@刘铎Derek 感谢小德哥 悉心指导 哈哈哈

本文标题:我与 Kotlin 的爱恨情仇之浅谈 block

本文链接:https://www.haomeiwen.com/subject/ftwixxtx.html