Swift的优势
结构体
可以包含函数,功能上,比类少的仅仅是继承。这其实是优点,用协议,用组合来代替继承,更容易让人理解。
面向对象和非面向对象的设计思维都可以用结构体
值类型,隔离性好,降低了耦合度,也减少了让人难以理解的bug出现。整体的效率由底层系统函数保证,并不会有多少的降低,对于应用开发者来讲,不需要操心。
在使用上,首先要将结构体当做一个比类要小的概念,用来定义Model,各种数据结构。这也是结构体最重要的作用。作为参数,作为接口,进行传递,这方面,比类要好很多。
在另一方面,可以将结构体当做一个比类更大一种结构,把它当做一个容器来使用,作用相当于UIView。内部的成员函数,返回这个容器本身,就能实现连续用“.”来调用的链式结构,使用很方便。Alamofire中Rquest,Manager都是这种用法的典范
枚举
枚举中可以包含函数,计算属性本质上也是函数。跟结构体相比,不能定义存储型变量,这个限制还是比较大的,应该将枚举用在结构体不方便的地方。将结构体加枚举的方式结合起来,可以替代很多场景下类的工作。枚举和结构体都是值类型,隔离性好,副作用少,推荐使用。
大多数情况下,应该将枚举作为比结构体更小的一个概念。用枚举最基本的含义,对那种有限种情况的场景进行抽象,防止非法的的输入输出,作为结构体的一个成员,配合结构体完成工作,方便理解。
在另一方面,枚举可以作为一种比结构体更大一个概念,作为一种容器,作用相当于UIView。结构体是值类型,代表了非面向对象的思想(面向协议,面向接口);类是引用类型,代表了面向对象的思想(主要是继承),同时也是以Object-C为基础的系统API的实现方式。而枚举就是将结构体和类型统一起来的一种“超大容器”。Alamofire中ParameterEncoding枚举类型就是这种用法的典范。
枚举的关联变量,提供了枚举类型携带参数信息的功能,比较好用,一定程度上弥补了枚举没有存储型变量的功能不足。在创建枚举变量的时候,设置关联变量的值;在使用枚举变量的时候,取出关联变量的值,起到了数据通信的作用。
枚举值可以是整数,也可以是String,这两种是应用最多的场景。也可以是什么也不是的一种“新类型”。这种外延的扩展给使用带来了很大的方便性。
Swift不排斥面向对象编程思想,同时也不局限于面向对象。对于结构化编程中一些好的方面也支持。枚举是统一这两者的一种重要“容器”。
可选类型
为什么说Swift比Object-C更安全?静态语言特性是本质,可选类型也是一个很大的因素。
在编程阶段,需要考虑有值无值,并且在各种情况下处理都要考虑,增加了程序员思考的内容,但是程序稳定后,将更加稳定。
多用?,少用,甚至不用!(系统自动生成的输出口可以不去动能够它),能够极大的降低程序崩溃的概率。
!主要是用在兼容Object-C的各种系统函数的,应用开发尽量不要去用。!和?之间的区别与联系也是很让人烧脑的,还是尽量避开为好。
!在框架设计的时候比较有用,不然不断地if let {}的推出,是一件很繁琐的事情。不过现在这种场景也不建议用了,有更好的方式。
guard let {} else {}结构建议多用。一方面,优先检查条件,及时退出,是结构化编程时代的一个良好习惯。另外,这也将可选类型提前转变为确定类型,方便后续的编码。
在框架编程中,可以考虑用协议,同时通过扩展,提供协议的默认实现,这会带来很大的方便。!基本上可以不用了。
函数
除了包含在类中的成员函数外,还有全局函数。不能滥用,但有些场景确实很方便。比如Alamofire文件中的那些顶层调用函数。
参数默认值功能比较好用,在定义函数的时候提供默认值,可以提供比较通用的功能,而调用的时候可以根据实际需求,只提供关心的参数,感觉就比较简单。比如print函数
大函数内部套小函数,可以将一些小工具抽象出来,方便今后重构,也不会打断当前思路。
引用循环
多用结构体和枚举,少用类,可以大幅度降低引用循环的发生。值类型,不需要考虑引用循环的问题
针对可选类型和确定类型,给出无主引用和弱引用两种方式,概念上会带来混淆。
捕获变量列表的方式来解决引用循环,方式更优雅。如果心情好,可以在每个闭包里面使用,也不用担心副作用。当然,最好还是需要的时候才用,做到这一点目前客观上还是有较大难度的。方式比Object-C中weak,strong,self的方式要好理解一些。
可见性
在project范围内,全工程可见,这个很方便,可以不用pch文件了
private,文档可见性,相当于C中的static global,对于限制全局变量的副作用有好处
public,framework中对外的导出接口,很直观
趋势
苹果已经明确,Swift将是未来的主力开发语言,最近2年,也让大家看到了这种趋势
Swift语言开源,这也是广受好评的一种趋势
Swift定位是安全,快速,跨平台的语言,这三个特性有非常强大的吸引力
在国外,Swift替代Object-C的趋势非常明显
gitHub上新增的第三方开源库,Swift版本要多余Object-C的版本;数量对比变化只是时间问题
Object-C的优势
Runtime
可以自动字典转模型
可以动态替换函数,进行热更新(JSPath),进行统计(替换ViewDidload等系统函数)... ...
可以通过关联变量的方式,为类动态添加属性
提供了动态特性,是一种动态语言,在开发中能带来很大的便利。而Swift中中Any和AnyObject,不但会带来混淆的困扰,使用上也没有id来得方便。
一些采用了runtime的优秀开源库,比如热更新JSPatch
NSString
下标是整数,定位,取子串等都比较方便;Swift的String是结构体,基于Unicode,下标index是NSRange,不是整数,比较难用;提供的操作辅助函数也是像指针一样,进行平移定位,不是很好用。
在当前的使用中(Swift),某些场景,可以定义NSString,进行一些操作,然后将结果转换为String(用as?),可以带来很大的方便。
在Swift中,大多数情况还是用String,并且始终记住是UnitCode编码,在某些场景下,这跟NSString由很大的不同。由于功能需要,需要用NSString操作,最后也应该转换为String,再对外输出。NSSting和Swift的String之间的相互转换由系统保证,应用开发者不需要有过多的担心。
成熟度
Object-C已经流行了4、5年了,大多数iOS开发者都熟悉;而Swift出来才2年,从1.0到2.0,到2.2,再到最近的3.0,API函数变化比较大
跟C++和C的兼容比Swift的好。如果是一个C++开发的库,Swift不能直接用,需要Object-C作为中间的过渡层才能使用。
在gitHub上,当前优秀的第三方库还是Object-C的多,比如WebViewJavascriptBridge
初始化函数的概念([[XXX alloc] init])比Swift的构造函数更容易理解,使用起来也更方便。
选择的建议
Swift从iOS7开始支持,但是支持得并不好;iOS8开始,Swift得到了比较好的支持。所以,如果要引入Swift,最低支持版本最好升级到iOS8
采用framework替换老旧的.a和.bundle,进行模块间隔离。
如果是新项目,并且最低支持iOS8以上,建议用Swift
如果是老项目,需要兼容iOS7以下的用户,建议保持Object-C不变
如果是老项目,最低支持已经升级到iOS8,并且团队有转Swift的意向。那么建议引入framework,一个模块一个模块,逐步重构,逐步替换。主工程保持Object-C不变,新加的framework用Swift。
如果已经是Swift为主的项目,没有必要考虑切回Object-C。如果遇到C++编写的库等Swift无法使用的情况,可以将这部分包含在一个framework中,这个framework用Object-C开发,等以后条件成熟了,再重构。Swift和Object-C之间的相互调用还是比较方便的。
总体建议,还是能用Swift的场景,就尽量用Swift。Object-C已经很成熟了,再用下去,提升空间也有限。而Swift刚出来不久,还没有到一统江湖的地步,尽早用,尽量多用,收益还是挺可观的。编程语言是一种工具,多用用,自然就熟了。
如果是runtime的重度依赖者,还是老老实实用Object-C吧;这和Swift的理念背道而驰。