详解Swift 2.0(一):苹果做的25项改变

更新时间:2015-07-24 10:24:17 点击次数:2031次

毫无疑问,Swift 2.0在2015全球开发者大会(Worldwide Developers Conference, WWDC 2015)上被发布的消息众人皆知。我会就该语言所发生的变化撰写一系列的文章,但目前我们先说说重点。


常规变化



内部的可见性

这解决了单元测试中的一个较大的难点。以前的做法:



现在可以启用testability,它就像C#中的InternalsVisibleTo。主应用程序目标模块的内部细节对测试模块可见。



这将导致测试忽略某些优化行为并保留稍后导入到测试模块中的那些内部符号。官方文档警告说,由于阻止了某些优化,因此这只适用于调试和测试版本。

模式匹配

switch语句的模式匹配(pattern matching)语法和“if let ..., .... where”语法一直在推广。可以在任何控制流中使用逗号操作符和where条件语句。还可以使用新的case条件语句,例如:if case .Silly(let a) { }。还有一种用于Optional<T>的特殊形式:if case let a? = anOptional { }。

模式匹配在循环语句中也可以使用:for case let thing? in array { }。

这又是值得单独成文的另一个特性。

Objective-C的泛型和__kindof的用法

在关于Swift的文章里谈论这个做甚?它的作用是使某些衔接更加清晰和简便。不求在这篇文章中面面俱到,我会再单起一篇文章阐述它。

错误处理

这不是我们一贯所认识的异常,这是一个使函数提前返回Result<T, Error>的操作,单隐藏了所有提前返回的对象,也隐藏了错误解析(error unwrapping)过程等内容。


[cpp] view plaincopy

  1. let systemAttributes: [NSObject: AnyObject]?  

  2. do {  

  3.     systemAttributes = try NSFileManager.defaultManager().attributesOfFileSystemForPath(documentDirectoryPath.last!)  

  4. catch _ {  

  5.     systemAttributes = nil  

  6. }  


它完美地与Objective-C进行互操作,Swift语言中,将标记为throws的方法作为选择器。这是使用NSError的方法,-(BOOL or nullable type)someMethodTakingParam:(type)param error:(NSError **),这种样式会自动引入标记为throws的方法。

应该明白的是这并不像Java中已经被检查过的异常(checked exception)那样。Swift语言并不关心异常的类型,或者处理或者不处理。这又是值得单独成文的另一功能特性。

Defer关键字

关键字defer也很重要,因为它可以取代传统C风格的“if(err) goto cleanup”。获得资源后接着就是defer { release_resource() }。然后不管函数返回结果如何,获得的资源都将被清理。这也意味着资源的释放紧随获取资源之后。这看起来不起眼儿,实则很重要。

NS_OPTIONS和OptionSetType

位操作枚举(bitwise enumeration)与数组风格的语法相结合,而不使用管道符“ | ”按位操作,并且具有所有范围的集合操作功能。检查一下是否具有contains功能的标志,或能够执行像isSubsetOf和isDisjointWith等这样集合操作的其他功能。这是显著的改进,表达了不直接对位进行操作的意愿。

这种变化意味着位操作枚举实际上不再是枚举了。将这些位操作枚举声明为结构体,实现OptionSetType协议,提供rawValue属性。并且创建值作为结构体的静态成员。Swift便会搞定其余的一切,自动提供所有集合的操作。这是我希望将来看到的更加明了的语法内容。

协议扩展

协议如今可以被扩展了,包括与类型约束有关的通用协议。还可以自己提供协议的默认实现。

先前,你不能你说:“我要使用方法X来扩展CollectionType,但只有集合中的类型满足某些条件才可以”。现在,你可以这么做,并且很多像map,filter和sort这样的全局函数已经进行了扩展。

这样就解决了很多痛点,这也是值得单独成文的内容。同时,要看看WWDC的面向协议编程(Protocol Oriented Programming)了解一些细节。

API审计

大量的API已经进一步进行了审计而更合理。举几个例子:



用translatesAutoresizingMaskToConstraints = false代替了setTranslatesAutoresizingMaskToConstrains(false)。

Availability属性

@available属性自Swift 1.2就存在了并且后续支持得很好。添加了一个新的陌生语法if#available(),为处理版本检查提供了支持。而不是插入你喜欢的方法。

遗憾的是你不能只声明一个属性UISearchController并将target设置为iOS 7,然后只允许访问类中的属性。Swift希望整个类的定义都可以或者不可以。

也可以不再采用协议,除非支持target设置中所有的操作系统版本,除非将整个类标记为只在更新的操作系统版本可用。

这意味着使用if #available()存在单独的子类和对创建适当对象的保护。

尽管如此,我个人还是发现了一个Bug,应用在iOS 4.0-4.1发生崩溃,由于编译器没有发出警告,方法只在iOS4.2才引入,因此我犹如与定时炸弹相伴。

C函数指针

Swift现在可以使用C函数指针,CFunctionPointer已不复存在。任何全局函数,嵌套函数和不捕获状态的闭包都可以作为一个C函数指针直接传递。你也可以调用来自C程序的函数。

你可以显示地使用新属性@convention(c),表示函数应该使用C调用约定,简单痛快!尽管我想不出在此对块(block)的支持有何用,作为所发生变化的一部分,@objc_block也被删掉了,使用@convention(block)取而代之。@convention(swift)默认支持所有函数和闭包。

这并不是编程语言所特有的。iOS 9含有不同版本的Swift标准库,并且在未来系统中将添加修正后的Swift标准库。结合新的App Thining技术,下载过程中苹果商店会将Swift标准库剥离出去的。我仍然在追根溯源地探求这究是如何工作的。

遗漏

明显的一个遗漏是处理异步代码。

苹果公司为我们提供了GCD,这是一个强大的基础类库,可以构建很多异步操作和并发原语。

然而,这些天我们做的每件事,构建用户接口和API都需要考虑异步性和并发性。我们把一个文件读操作锁定一段时间,对用户来说整个世界就都静止了。

这是个持续的痛点,不是多大的事儿,但如果经常性地每天重复,恐怕也是不行的。

C#和JavaScript都采用了async/await来为异步代码提供一流的语言支持。我想很多人都想知道,Swift会提供什么样的语法糖来帮助我们在实现异步操作方面确保正确性。我不知道在Swift 2.0发布的时间框架内是否会看到什么,但愿能有好的东西出现吧!

开放源码

宣布的内容中,反响强烈的无疑是Swift开放源代码。苹果公司已经承诺在今年底前开放源码,我们也没有理由对此表示怀疑。与苹果公司编译器团队成员讨论过程中,他们看起来似乎对此由衷地兴奋,无论如何坚决要干成这件事(我有点小失望,他们没有打造出经典的苹果然后宣布开源,但我仍然对此消息发自内心地感到高兴)。

结论

Swift 2.0有很多令人喜爱之处。苹果公司的Swift团队向大家承诺他们会迅速行动。到目前为止这些承诺已经被兑现。成为苹果平台上的开发人员是一个激动人心的时刻。


本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是一个个人学习交流的平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽,造成漏登,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

回到顶部
嘿,我来帮您!