2014年WWDC大会,苹果在毫无预兆的情况下,发布了Swift编程语言。这个语言刚发布就引起了广泛关注。我认为抛开Objective-C单独谈论Swift是不准确的。因此我们先从Objective-C谈起。 Objective-C语言 Objective-C语言是编写iOS/Mac程序的主要语言。编写iOS/Mac程序,除了Objective-C,还可以混合使用C/C++,另外也可以嵌入一些脚本语言。但在UI部分,使用Objective-C最为直接自然。 Objective-C和C++都是C语言的扩展。C++十多年前就已名满天下,而Objective-C虽然也诞生了二十多年,但在iPhone发布之前,一直不温不火。 这两种语言都支持面向对象,设计理念却十分不同。C++的面向对象部分更强调类型,需要知道对象的类型才能调用对象的函数。而Objective-C则更强调消息的发送。另外,C++很看重运行速度,运行时基本不包含类型信息,整个运行环境是静态的。而Objective-C则牺牲了一点运行速度,换来更加灵活、完全动态的运行时环境。 Objective-C的缺点 初学iOS开发,第一个门槛就是Objective-C的语法,它的语法跟主流的语言十分不同。有些人甚至觉得它的语法丑陋得无法忍受。另外,Objective-C的代码看起来比较啰嗦。如同一个人,看起来怪怪的,不太合群,熟悉之后又显得太过唠叨。 Objective-C缺少一些语言的保护机制,成员函数不区分公有私有,且没有命名空间。模块与模块之间需要加前缀来区分,比如Foundation模块类前面都加上NS前缀,表示NextStep。 Objective-C兼容C语言。因此C语言很多设计不合理的地方也被引入了Objective-C中。另外,Objective-C没有采用GC(垃圾回收),它的内存管理采用引用计数的方式,后期引入ARC (自动引用计数),这种内存管理方式相比GC而言,对程序员的要求较高。 当然,Objective-C也有很多优点。甚至可以说Objective-C的某些缺点,从另一角度看,恰恰是它的优点。 Objective-C的优点 动态运行环境,适合UI编程 在Objective-C中,如下语法并非单纯的函数调用,而是向某对象发送消息。 Objective-C的运行环境是动态的,可以在运行时判断出某对象能否响应某种消息,而不管此对象是什么类型。 UI程序大框架就是消息处理。系统接受到某种消息(如程序启动了、列表被选中了、手指在屏幕上移动了)之后交给可以响应这个消息的对象来处理,而不关心这个对象到底是什么类型。 方便与C/C++ 混合使用 Objective-C中的C扩展部分,使用符号@开头。比如@class、@interface、@"Hello,World"。而它的消息发送语法则是使用中括号而不是圆括号。 这种独特而另类的语法使得Objective-C的代码,就算跟C++代码混在一起,也很容易被识别出来。此外,将文件扩展名修改成mm就可以在同一文件中混合使用Objective-C和C++。两者直接相互调用,不用经过任何间接层。在需要大量使用C++的场合(比如游戏),这种混编特性很有用。 运行速度相对较快 Objective-C编译后是机器原生指令,运行时环境也小而紧凑。它采用引用计数的内存管理方式,并引入ARC。ARC比GC更容易引起编程错误,但却比GC快。而在性能很重要的场合,Objective-C也很容易直接调用C/C++代码。相对于其他使用虚拟机、采用GC以及间接调用C/C++的移动平台,速度优势非常明显。 Swift和Objective-C的联系 苹果一直在改进Objective-C,默认编译器由GCC换成了LLVM,并先后加入literal、block、ARC、Module等特性。我认为最大的两点改进为以下两点。 ARC+弱引用,本质还是引用计数。但从人手调用retain、release,转成编译器自动插入代码是个质的飞跃。 block+GCD,block引入函数式风格的代码块,而GCD则大大简化了异步代码编写方式。 WWDC之后,我开始思考一个问题,苹果为什么不继续改进Objective-C,而发布Swift这门新语言呢?这个问题只有苹果自己知道,其他人只能猜测。 可能的原因有以下几个方面。 Swift表面看起来很简单,语法跟流行的C#、JavaScript、C++等语言相似,可以吸引更多的开发者。 Objective-C因为需要兼容C,所以限制了它的改进。而Swift没有历史包袱,可以自由采用最新的语言设计研究成果。 设计者的个人品位,Chris Lattner不习惯Objective-C的语法,就去设计了一个新的。当然,这是玩笑话,不要太当真。 Swift虽然是新语言,却融合了Objective-C的很多特性。读Swift的文档会发现,Objective-C与Swift的联系十分密切。Objective-C使用的很多底层技术,被应用到Swift中。 Swift与Objective-C共用同一套运行时环境 我们编写程序,让程序运行起来,被机器执行的代码并非全部是由我们自己来编写的。需要同时运行很多预先写好的支持性的代码,才能让我们自己的代码运行起来。程序并非单独存在的,运行时处在一定的环境当中。我总联想到很多小蚂蚁在泥土上面爬,而我自己写的程序只是其中的一只。 Swift跟Objective-C编译出的程序代码运行在同一套运行环境上面。Swift的类型可以桥接到Objective-C的类型,反之亦然。Swift编写的代码可以调用Objective-C编写的代码,反之也一样。 Objective-C之前积累下来的大量类库,实现不用改写Swift就可以直接调用。 同一个工程,可以同时使用Swift和Objective-C Objective-C在一端,Swift在另一端,两端经中间文件进行桥接。桥接文件包含Objective-C的头文件,编译时自动转成Swift可以识别的形式。Swift就可以使用Objective-C的类和它的函数。 在Swift的类中,加上@objc(类名)的字样,Objective-C也可以使用Swift编写的类。但Swift跟C++的相互调用,需要Objective-C来封装。 总的来说,共同使用Swift和Objective-C/C++还算方便,但已不能将几种语言的代码,混写在同一文件。大概是因为Swfit的语法不像Objective-C那样独特,混写难以将Swift的代码识别出来。
|