六月 26, 2018

Swift学习心得

前言

Swift是一门比较高级的语言,参考了很多其他语言,你可以从swift上看到很多其他语言的影子,事实上你要是学过kotlin这门语言的话,你会发现swift跟kotlin太像了。先不管这两门语言谁先谁后出的,但是总的来说,都是为了简化编程,提高编程效率。

Kotlin和java都是基于jvm的,而swfit和object-c其实都是基于Fundation的,这也就是为什么kotlin和java或者swift和object-c可以混编的根本。我们甚至可以直接把这些语言认为是一种语法糖,反正最终都是由编译器编译成字节码来运行在各自的”虚拟机”上的。

心得

Swift这门语言相对于object-c来说大部分的改进都是让编码更加的方便了,但是有部分地方的改动让一些初学者有点接受不了,而且有些地方个人觉得有点改的不伦不类。

  1. 就拿swift的闭包来说,从语法来说,没有object-c来的简单直接,语法很复杂,很容易出错。还引入自动闭包的概念,要是遇上一些喜欢卖弄技术的开发同事就懵逼了,因为你压根就看不懂这行代码是调用的闭包还是方法。而且Xcode自动完成功能也支持的不到位,在intellije 上用过kotlin的同学就会深有体会。

  2. Swift引入了结构体,其实结构体并不是Swift特有的,C和C++就有,但是问题是Swift把几乎所有的基础类型都定义为结构体,array、dictionary、string都是结构体,而这几个基本类型在OC中是类,因此对于这个更改,对于实际的编码还是需要注意些,毕竟结构体和类的存储方式完全不一样的,结构体是值类型,而类是引用类型,这些区别需要在赋值、传参的时候需要注意(事实上,swift已经做了优化,并不会每次传参都会发生值拷贝的行为,只会在实际需要改变的时候才会去拷贝。但是既然有这样的优化,那为何还改成结构体!!!!感觉有点多此一举)。目前还不好直接说这样的改变是好还是坏,只能在实际的项目中慢慢摸索验证吧。另外,Swift中的结构体是必须要初始化的,这一点相对于C、C++来说是不一样的,不过这样的改变可以理解为运行时安全,确保所有的值都是正确的。

  3. Swift对于函数的调用有一个叫做标签的功能,私以为这个功能是为了跟OC中的方法定义对接的,估计是fundation框架本身的限制吧,这个功能在OC中倒还好并没有觉得特别的突兀,但是Swift还是有这个限制就觉得有点突兀了,暂时还没有从其他的语言中看到类似的功能的,实在有点难以接收,再加上Xcode的代码自动完成功能并不那么智能,对于初学者来说,调用一些复杂的方法会比较蛋疼,尤其是那些带有多个闭包的复杂方法。对于我这种OC的老司机来说,第一次调用RxSwift中的相关方法的时候也是一度把我折腾了够呛。

  4. 对于Switch判断来说,swift可以说提供了史无前例的大改进,比kotlin中的switch判断还要来得便利以及先进。基本上大多数的条件判断都可以使用switch来代替了。相当的强大,强烈推荐使用。

  5. 不管是OC还是Swift,虽然都标榜是面向对象的语言,但是一些面向对象的特性严重缺失。比如抽象类、抽象方法、保护类。这个估计只能理解为是foundation不支持吧。

  6. 以前因为做过C#开发,对立面的linq技术是念念不忘,java8基本已经有类似的API了,而kotlin也有类似的实现,真希望OC、swift也有,但是swift还是没有,不过swfit在集合操作上也添加了不少的API,多少弥补了些差距,但是依然不方便,尤其是linq那样的链式操作方式相当方便。没办法,只能拿RxSwift来凑数了。

  7. Swift的内存管理延续了OC中的内存管理,本质上还是foundation上的CFRetain和CFRelease那一套。因此,对于从OC转过来的开发者来说内存管理还是比较熟悉的。由于Swift默认就支持ARC,因此在实际的开发过程中注意避免循环引用的问题,解决循环引用的方法跟OC的也是一样的,谁让OC和swift都是同一个祖宗呢!不过swift引入了一个叫做”unowned”的无主引用的概念,其实就是OC中的assign啦。不过对于闭包的循环引用解决方式的语法实在有点不习惯。感觉是非常奇葩的语法

  8. Swift增加了一种可空类型,也就是在类型后添加?表示,表示这个变量或者返回值是可空的,但是这样的变化即带来了便利同时也带来了额外的麻烦,如果是直接从OC转过来的,可能对这样的方式一时半会适应不了,也无法判断这样的改进到底是好还是不好。Swift还增加一个叫做“可选链式调用的”方法,熟悉kotlin的同学肯定很熟悉,这货跟kotlin是一模一样滴,但是由于swift的本身语法特性,使得实际的实现过程还是有点不习惯,这里的不习惯主要是语法层面的。哎,只能说这很”apple”。

  9. 有一点不得不吐槽Swift,语法实在有点糟糕。从java转kotlin是一个很顺利的过程,无需多少学习成本就能很快上手。但是OC转Swifit就的先习惯这些比较奇怪语法,然后才能继续后面的编码,根本谈不上无缝转换。当然,熟悉以后就是另外一回事,但是这说明一个学习成本的问题。

  10. 再说说Swift的错误处理,在OC中我们也是可以处理异常或者跑出异常的,但是在实际的OC编码过程中,我们几乎很少会去以异常的形式来设计我们的代码,更多的使用“NSError”,这可能跟评估官方的设计习惯有关,因为苹果本身在自己的API中大多数采用的是error的形式,很少采用throw。但是在Swift中可以说是有了根本性的改变,几乎都是采用抛异常的方式来设计了。有一点不得不提,那就是Swift在抛异常的内部处理方式上跟其他语言是不一样的,在性能上得到了根本性的加强,几乎可以忽略抛异常带来的性能损耗,因此使得我们在实际的编码过程中直接已抛异常的形式来代替部分return。这样的改变对于我们的架构设计带来了更多的可选项。最后还是不得不吐槽下异常处理上的奇怪语法,你得使用 do - try - catch 的形式来处理,而不是其他语言那样的try-catch方式,不过这样的设计也可以理解为为了配合其他语言特性故意这样设计的,比如处理可空的try等等。另外一个swift中try-catch是没有finally的,取而代之的是“defer”,语法和调用顺序也是比较蛋疼的,初次接触很容易混乱。

  11. Swift对于类的扩展进行了大幅度的变更,跟kotlin更加接近了,但是相对于OC的扩展来说,更加的方便了,但是少了可存储属性的扩展,在OC中可以任意扩展扩展、方法,但是Swift中却只能扩展计算属性,其实这个扩展说白了就是扩展一个方法,跟真正的属性扩展感觉差了点意思。

  12. 再来说说泛型,泛型这个概念,在早期的OC中是没有的, 事实上到目前为止也是没有一个成型的泛型概念的,但是借助IDE的帮助,对于Array、Dictionary等数据类型倒是勉强可以实现简单的泛型,但是跟真正的泛型相比根本不是一回事。而对于Swift来说,天生就支持泛型,对于接触过其他语言的人来说,泛型对于程序的设计影响是很大的,可以说有泛型和没泛型在程序的设计思想上可以使两个不同的领域,当然这么说确实有点夸大泛型的概念了,但是也是强调了泛型的重要性。而目前Swift对于泛型的支持已经很到位了,该有的都有了。

  13. Swift增加了访问控制的一些相关关键字,比如openpublicprivateInternalfileprivate等关键字来实现不同的访问级别控制。但是这里的访问控制跟其他语言中的有点不一样,尤其是openpublic,对于那些接触过java或者C++的人来说,这两个关键字有时会会搞错用途。fileprivate其实就是相当于在OC中直接将类的定义和实现写在.m文件中。Swift中的访问控制限制很多,一不小心就会踩雷。

Posted in iOS

发表评论

电子邮件地址不会被公开。 必填项已用*标注