学习Swift编程(准备好进行黄金时段了吗())

本文概述

  • 在Swift之前:你将使用Objective-C, 并且会喜欢…
  • … 或者可能不是。输入新的iOS语言Swift。
  • 与Objective-C的兼容性
  • 比Objective-C快?
  • 编译器
  • 社区
  • 我应该学习Swift吗?
苹果公司于今年6月推出了Swift, 这是一种用于编写iOS应用的新编程语言, 在整个iOS开发者社区中引起了极大的轰动和兴奋。
自发布以来, 许多iOS开发人员一直在努力就是否, 如何以及何时从Objective-C过渡到Swift的问题。对于每个团队和每个项目, 该问题的答案当然都会有所不同。
你可以阅读许多文章, 其中涵盖了Swift的许多优点。因此, 在本文中, 我们不再专注于相同的观点, 而是着重于你在学习使用Swift开发应用程序之前可能要考虑的一些问题。
学习Swift编程(准备好进行黄金时段了吗())

文章图片
但是首先, 让我们把时钟倒回一点……
在Swift之前:你将使用Objective-C, 并且会喜欢… 【学习Swift编程(准备好进行黄金时段了吗())】那年是2010年。iPhone还不到3年, 而为iPhone编写本机应用程序的能力只有大约2年。当年4月8日, Apple宣布了iPhone OS版本。 iPhone OS(在将其更名为iOS之前)包括诱人的新功能, 例如多任务处理, 快速的应用程序切换和后台服务。可以理解, iPhone开发人员渴望获得新的SDK, 并开始使用所有这些令人兴奋的新功能。
但是iPhone OS 4 SDK包含了意外的重磅炸弹。这个重磅炸弹不在软件中, 而是在使用协议中。使用iPhone OS 4 SDK, 开发者协议的3.3.1节已更新, 其中包括以下令人困扰的语言:
应用程序最初必须使用Objective-C, C, C ++编写, 并且只有用C, C ++和Objective-C编写的代码才可以编译并直接链接到Documented API。 – iPhone OS 4 SDK开发人员协议的3.3.1节
不用说, 这一新限制使许多开发人员感到惊讶。史蒂夫·乔布斯本人提供的更改的正式原因是为了防止使用跨平台工具, 例如最近发布的Flash CS5。引用了乔布斯的话说:” 平台与开发人员之间的中间层最终会产生[sic]次标准应用程序” 。但是, 苹果公司与这些” 中间层” 作斗争的方法是限制可以用来编写iPhone应用程序的编程语言, 这揭示了苹果公司的更多想法:Objective-C对任何人都应该足够好。
可以肯定地说, 因为Objective-C连续两年获得了Tiobe Index的” 年度最佳编程语言” 奖。但事实是, Objective-C的普及是不断增长的应用生态系统的功能, 而不是相反。甚至在2010年, 许多人就对Objective-C感到不满意, 结果, 以其他编程语言编写iPhone应用程序的替代方法已经出现。
最终, 在广大开发人员的压力下, 苹果仅在五个月后就将这些更改撤回了《 SDK开发人员协议》第3.3.1节。尽管如此, 消息仍然很明确:如果你想为iPhone编写应用程序, 则可能应该使用Objective-C。
… 或者可能不是。输入新的iOS语言Swift。 从那次事件到2014年6月, 苹果公司向开发人员介绍了其新语言Swift, 这是过去四年。如果说4年前的消息是Apple对Objective-C完全满意, 那么Swift的介绍中发送的消息就是Apple终于准备承认事实。 Objective-C不一定是编写移动应用程序的最佳语言。
关于Swift是比Objective-C更” 现代” 的语言, 已经有很多说法。如果你对如何学习Swift编程语言感兴趣, 则可能需要查看有关从Objective-C迁移到Swift的指南。
不过, 你应该注意的是, Objective-C和Swift语言之间有两个重要区别:
  1. Swift不是C语言的严格超集。
  2. Swift是静态类型的, 不是动态类型的。
不是严格的C超集意味着Swift可以自由使用否则将不允许的语法构造。例如, 这使得在Swift中实现自定义运算符成为可能。
静态类型化意味着Swift可以利用诸如Haskell之类的语言在类型系统方面的最新发展。
尽管开发了4年之后才向公众展示, 但是Swift仍然是一种年轻的编程语言, 因此它带有一些警告。
与Objective-C的兼容性 iOS与OS X具有相同的传统, 而OS X的历史则源于1989年首次发布的NeXTSTEP操作系统。NeXTSTEP最初主要是用Objective-C编写的, 而OS X和iOS中的许多核心库都可以追溯到它们的根源。回到这些原始实现的方式。 (顺便说一下, 这是在诸如NSString之类的核心类上找到的普遍存在的” NS” 前缀的来源。)虽然理论上Swift可以在没有这些核心库的情况下存在, 但现实情况是你可能会在不久的将来编写任何Swift程序将必须与Objective-C交互。
值得赞扬的是, Swift背后的开发人员做了出色的工作, 使与现有Objective-C库的交互尽可能轻松。但这并不是说该过程完全没有痛苦。 Apple提供了一个有用的指南, 解释了如何从Swift调用Objective-C代码, 反之亦然, 但是需要注意一些重要的阻抗不匹配问题。
也许最明显的不匹配与头文件有关。由于Objective-C具有C根, 因此仍然需要在调用函数之前对其进行声明。调出库时, 这些声明将在库的头文件中找到。但是, Swift不使用头文件。因此, 如果要从Objective-C调用Swift代码, 则首先需要创建一个” 桥接标头” 。尽管从概念上看这似乎并不复杂, 但实际上, 这实际上是一项艰巨的任务。
Swift和Objective-C之间接口的另一套复杂性是由于它们类型系统的固有差异。 Swift从其他现代语言中汲取了灵感, 并取消了nil的概念。替换为Swift的可选类型。例如, 仅在文件已存在的情况下打开文件的方法将具有File的返回类型? (而不仅仅是File)在Swift中。通过跟踪所有类型都是可选的位置, Swift编译器可以有效地使其不可能遇到可怕的” 空指针错误” 。当然, 除非你要调用Objective-C。由于Objective-C无法保证不返回nil, 因此Swift具有一种特殊类型的类型, 称为” 隐式解包的可选类型” , 该类型在调用Objective-C代码时使用。在Swift语言中, 这些类型可以被视为可选类型, 以及存在检查所需的所有伴随开销。另外, 它们可以与任何非可选类型一样使用, 但是如果Objective-C确实返回nil, 则将导致运行时错误, 因此你将失去某些Swift的编译时安全性保证。
最后, 当在Swift和Objective-C之间进行编程时, 要考虑的细微差别是与这两种语言的秘密创建对象和类的方式有关。由于其动态特性, Objective-C利用动态调度来调用对象上的方法(通过objc_msgSend)。 Swift当然可以使用动态调度, 但是由于它是静态类型的, 因此它还可以选择使用vtable为每个方法存储函数指针。 Swift使用这两种机制中的哪一种取决于两个因素。平面旧Swift对象将使用vtable机制, 除非使用@objc Swift属性对类中的类或方法进行注释。从Objective-C类继承的Swift类将对继承的方法使用动态分派, 但不会对子类引入的任何新方法使用动态分派(尽管同样, 你可以使用@objc属性强制使用动态分派)。无论如何, Swift代码始终可以使用Swift类, 但是Objective-C代码只能使用已正确注释的Swift对象和方法。
比Objective-C快? 当苹果推出它的发布时, 特别强调的Swift的好处之一就是它的速度。当你考虑到苹果通常不愿意从Objective-C切换到高级语言的一个原因是, Objective-C本质上是C的扩展, 能够创建更快, 更高效的程序时, 这是可以理解的而不是像Python或Ruby之类的东西。即便如此, 在绝对性能方面, Objective-C并不是火箭飞船, 其中大部分可以归因于动态类型化。因此, 在Swift采用静态类型系统的情况下, 人们期望Swift至少应与Objective-C一样快或更快。
当然, 俗话说:” 谎言分为三种:谎言, 该死的谎言和基准。” (或者类似的东西……)当然, Swift语言运行速度更快的原因有很多。不幸的是, 似乎Swift利用Apple的ARC(自动引用计数)技术进行内存管理的方式有时会导致Swift的编译器生成速度明显慢的程序, 尤其是在优化设置较低的情况下(例如在开发过程中可能使用的设置)。好消息是, 似乎Swift的改进正在不断解决这个问题, 因此Swift可能会在不久的将来以至少与Objective-C一样快或更快的速度生成可执行文件。
不过, Swift的速度还有一个警告。 Swift的全部要点是, 开发人员将不会编写与使用Objective-C编写的代码相同的代码。这对性能意味着什么?好吧, 当然, 这意味着比较简单的基准测试无法揭示Swift和Objective-C之间的性能比较。这也意味着比较生成的可执行文件的绝对运行时性能仅能说明一半。
每个人都想要快速的程序, 但有时开发速度也很重要(如果不是更高的话)。在这方面, 一种更具表现力的语言, 能够用更少的代码行完成更多的工作, 可能会带来巨大的好处。另一方面, 当使用编译语言进行编辑, 编译, 运行, 调试周期占据程序员大部分时间时, 缓慢的编译器确实会损害生产率。尽管证据主要是轶事, 但看来Swift编译器目前的运行速度足够慢而令人讨厌, 尤其是在使用行使Swift高级类型系统的代码时。甚至有一个小组发现编译速度有问题, 足以促使人们切换回Objective-C。
编译器 说到Swift编译器, 当考虑切换到新的Swift语言时, 它本身就是更多警告的来源。除了编译速度外, 随着Swift从苹果公司与其合作的一小批开发人员中脱颖而出, 并在大众中释放出来, 编译器已开始在压力下显示出裂缝。甚至还有一个完整的GitHub存储库, 专用于收集将导致Swift编译器崩溃的代码示例。
还有一个问题是Swift编译器将如何变化。 GitHub上的另一个项目正在收集社区的猜测和分析, 以了解Swift可能会存储哪些更改。例如, 自定义运算符可能会对解析器造成很大的压力。最初, Swift中的自定义运算符不能使用问号(?)字符。尽管在最新的Swift版本中已修复了该问题, 但不断增长的Swift开发人员社区不断提出要求, 以提供更多有效的自定义操作符灵活性。
每当你听到某种语言的解析器不断变化时, 它都应该让你暂停一下。语言的解析器是编程语言的灵魂。在应用任何语言语义来赋予代码含义之前, 解析器首先确定什么是有效代码, 哪些不是有效代码。因此, 令人鼓舞的是, 苹果公司已承诺确保Swift的某种程度的运行时兼容性。但是, 这并不一定保证Swift代码将在无需为每个新版本的Xcode和/或iOS重新编译的情况下运行。它也不能保证你不需要重写部分Swift代码即可与以后的Swift版本保持兼容。但是, 苹果再次承诺使这一过程尽可能轻松的承诺至少是一个小小的安慰。
社区 很久以前, 常识说, 仅凭它们各自社区的力量, 它们本应被归类为失败的技术垃圾箱, 这是有史以来创建的一些最糟糕的编程语言(将不为人知)受到鼓舞。同时, 由于社区缺乏而无法掌握的非常不错的编程语言的集合实在太多了。强大的社区制作教程, 回答有关Stack Overflow的问题, 在线或在会议上亲自聚会, 共享故事, 技巧和窍门, 并相互编写和共享有用的库。选择项目使用哪种语言时, 社区绝对是要考虑的事情。
令人遗憾的是, iOS / Objective-C社区并不以友好和热情而闻名。这种情况正在逐渐发生变化, 开源在Objective-C开发中越来越扮演着越来越重要的角色。不过, 在早期阶段, 很难说出Swift社区的发展前景。它是否将主要由孤立的开发人员组成, 这些开发人员仅使用官方的Apple API和他们自己的私人代码集?还是将成为一个充满活力的团体社区, 共享提示, 技巧和有用的库?
社区角色的另一个方面是Swift开发人员本身的角色。编程的总体趋势是从专有的编程语言和平台转向开源解决方案。开源开发, 尤其是在编程语言和运行时级别的开发, 可能是真正的优势。尽管Swift开发人员多次表示他们打算完全开源Swift语言和运行时, 但这尚未发生, 因此必须谨慎。
也就是说, Swift背后的开发人员与长期运行的LLVM项目背后的一些开发人员相同。 LLVM不是一个完美的类比, 因为它是伊利诺伊大学香槟分校的一个项目, 以开放的形式开始了。但是值得称赞的是, 即使在大多数开发人员转而为苹果公司工作之后, 核心开发人员仍然非常开放并与社区互动。完全有理由期望Swift语言将继续(主要)在公开场合开发, 尽管社区中的补丁和功能建议是否会进入该语言尚待观察。
我应该学习Swift吗? 当然, 这里没有” 一刀切” 的答案。与往常一样, 为工作选择合适的工具需要对相关项目的所有细节都有深入的了解。当然, 目前, Objective-C仍然是iOS开发的” 安全” 选择, 但Swift绝对值得考虑。
Swift给iOS开发带来的最重大变化是, 许多开发人员将首次问自己一个问题:” 我应该使用哪种语言?” 考虑到Apple, Objective-C和iOS平台的历史, 仅此更改就令人兴奋, 特别是考虑到选择不是二进制的。尽管苹果明确表示了他们的偏爱, 但整个iOS开发人员社区多年来一直在努力工作, 已经为该问题提供了更多可能的答案。

    推荐阅读