Swift 2.3-> 3.0

是否从Swift2.3升级到3.0呢?git

若是你有一个意义很是重大的Swift编码库(就像咱们在VTS中作的同样),那么别犹豫了,赶快更新吧。另外为了项目的须要,Xcode的更新,跟随苹果的步伐,最新的技术,仍是麻溜的跟上把。github

可是若是你的Swift代码不是很是的繁重,那么你就直接忽略2.3吧。objective-c

下面有一些事情须要记住:swift

1.依赖库很是重要,确保你的依赖库支持2.3仍是3.0-大多数的lib/framework是二者都支持的(Alamofire,Charts).然而升级到3.0是你的惟一途径。新的发展将会在Swift3.0展开。全部的swift2.3版本的相关依赖库将会被冻结,也就是不在更新。闭包

2.Xcode8.x 将会移除对Swift2.3的支持。Swift2.3注定是大型工程的一个过渡品。因此咱们须要努力的升级到swift3.0app

3.若是你有一个私有的CocoaPods用于分享代码在多个工程中,那么你不得不立刻更新。dom

固然你能够只更新到2.3,可是你只能推迟,由于在发布Xcode9以前你必须移植到Swift3。async

 

将问题从Swift2.2迁移到2.3ide

这个迁移可能将Range<T>到CountableRange<T>.可是CountableRange<T>只存在于Swift3函数

迁移者将会添加评论 /* 迁移者 修复:使用变量类型为: DispatchSpecificKey*/去使用dispatch_queue_set_specific() 这是惟一将来相关在Swift3迁移中。

 

将问题从Swift2.x迁移到3.0

Swift3.0是一个打破一切的版本。swift3意味着打破一切而且移除了全部不利于一个语言长期发展的不利因素。这固然也意味着不少的东西被改变了。你也须要去改变这些使你的工程更加兼容。

 

Swift 2.3

Swift2.3是一个很是小的更新。具体多么小呢?实际上,这里仅仅只有一个改变。OC代码在编译时为空的检查在苹果的SDK中被更新。

// Swift 2.2
  let image = CIImage(MTLTexture: texture, options: options)
  let extent = image.extent // can crash
   
  // Swift 3.0
  let image = CIImage(MTLTexture: texture, options: options)!
  // or
  if let image = CIImage(MTLTexture: texture, options: options) {
 
  }

其余的变化包括一些小的重命名和一些可选类型的初始化如今返回了他们应该返回的类型而再也不是可选类型。这些应用就想从bundle初始化nib同样。

 

Swift3.0

重大的更改(你必须须要注意)

私有的定义已经被更改了,下面来介绍一下fileprivate

之前格式化的私有如今在Swift3.0中变成了fileprivate。一个fileprivate可使用在一个Extension中

可是一个私有private的变量不可使用在一个Extension的类中

学习更多的关于这个变化,请点击这里

public的定义也被改变了。下面来介绍一下open的定义

目前,声明一个类或者属性public提供了两种实用性:

1.容许外部的modules使用class/member.

2.容许外部的modules继承class/member.

在swift3中,public就是外部可用的,可是不能继承。之前的功能被open给封装了。

学习更多的关于这个变化,请点击这里

 

动词和名词

以d结尾的函数如今返回这个对象的一个实例

// Before
  var myArray = [ 1 ,3, 2, 5, 4 ]
  myArray.sort() // returns a new sorted version of `myArray`
  myArray.sortInPlace() // sorts in place
   
  // After
  myArray.sort() // sorts in place
  myArray.sorted() // returns a new sorted version of `myArray`.

 

这个变化一样适用于reverse和reversed,enumerate和enumerated等等

 

OC的布尔类型如今所有使用前缀 is ,Foundation 类型再也不使用NS前缀了(这将不会有冲突,例如NSString仍然有前缀,要否则这将会和String冲突)

 

Foundation类型如今可使用Swift的let和var定义很是nice的展现出来

//before
  var myDate = Date()
  myDate.addTimeInterval(60) // OK
   
  //after
  let myOtherDate = Date()
 

myOtherDate.addTimeInterval(60) // Error, as expected

 

学习更多的关于这个变化,请点击这里

 

引入做为一个成员

如今的C函数将会被引入做为方法。导入者将会常常自动地推断这些map。那就意味着使用老的C的API感受更天然了,更和谐在Swift。就拿point为例。CoreGraphics API。CoreGraphics已经再也不更新了在这个版本中

  // Before
  let topLeft = bounds.origin
  let bottomRight = CGPoint(x: bounds.size.width, y: bounds.size.height)
  let path = CGPathCreateMutable()
  CGPathMoveToPoint(path, &transform, topLeft.x, topLeft.y)
  CGPathAddLineToPoint(path, &transform, CGRectGetMidX(bounds), bottomRight.y)
  CGPathAddLineToPoint(path, &transform, bottomRight.x, topLeft.y)
  CGPathAddLineToPoint(path, &transform, topLeft.x, topLeft.y)
  CGPathAddLineToPoint(path, &transform, topLeft.x, bottomRight.y)
  CGPathAddLineToPoint(path, &transform, bottomRight.x, bottomRight.y)
  CGPathAddLineToPoint(path, &transform, bottomRight.x, topLeft.y)
  CGContextAddPath(context, path)
   
  // After
  let topLeft = bounds.origin
  let bottomRight = CGPoint(x: bounds.size.width, y: bounds.size.height)
  let path = CGMutablePath()
  path.move(transform: &transform, x: topLeft.x, y: topLeft.y)
  path.addLine(transform: &transform, x: bounds.midX, y: bottomRight.y)
  path.addLine(transform: &transform, x: bottomRight.x, y: topLeft.y)
  path.addLine(transform: &transform, x: topLeft.x, y: topLeft.y)
  path.addLine(transform: &transform, x: topLeft.x, y: bottomRight.y)
  path.addLine(transform: &transform, x: bottomRight.x, y: bottomRight.y)
  path.addLine(transform: &transform, x: bottomRight.x, y: topLeft.y)
  context.addPath(path)

 

学习更多的关于这个变化,请点击这里

 

驼峰标示的改变

在枚举和属性中。首字母大写的驼峰标示已经被小写所代替

// Before let red = UIColor.redColor().CGColor

// After let red = UIColor.red.cgColor

 

(我最喜欢的改变)重构了条件条款

你将不能在guard,if,while里面使用where关键词了。可是你仍然能够将他应用在循环(for-in-where)

// Before
  if let x = x where z == 2 {
  // Do stuff
  }
   
  // After
  if let x = x, z == 2 {
  // Do stuff
  }

 

仍然还有一些改变在case的条款中

学习更多的关于这个变化,请点击这里

 

第一个参数标签的一致性

第一个参数的名字默认是必须的如今

func remix(aSong: Song) {
...  
}  
   
// Before  
let song = Song()  
remix(song)  
   
// After  
let song = Song()  
remix(aSong: song)  

 

学习更多的关于这个变化,请点击这里

 

(我最喜欢的改变)处理了隐式的打开可选类型

我认为若是你有一个分享的语言,那么在迁移的过程当中这个改变是值得的。那么究竟是什么呢?

OC类型之前只有隐式解包类型!的属性。可是如今有了包裹类型?这能够被用到任何地方除了这里:

let legacyType = SomeObjCObject()

let starsArray = legacyType.stars     // Array of [Star!] 

学习更多的关于这个变化,请点击这里

 

更好的翻译关于OC的API

命名更加的清晰明确了

let path = UIBezierPath()
let point = CGPoint(x: 2, y: 3)  
let string = NSString("Hello world!")  
// Before  
path.moveToPoint(point)  
string.characterAtIndex(3)  
// After  
path.move(to: point)  
string.character(at: 3)  

 

学习更多的关于这个变化,请点击这里

 

现代化的调度:dispatching

// Before
let queue = dispatch_queue_create("com.test.myqueue", nil)  
dispatch_async(queue) {  
print("Hello World")  
}  
// After  
let queue = DispatchQueue(label: "com.test.myqueue")  
queue.asynchronously {  
print("Hello World")  
}  

学习更多的关于这个变化,请点击这里

 

集合类型有了新的展示形式

之前,当你想要在集合类型中从一个index一到另一个,你须要使用index的successor方法。可是如今你使用c.index(after:index)就可让collection之间的移动成为现实。collection如今有了一个任何可比较类型的index

 

myIndex.successor() => myCollection.index(after: myIndex)
myIndex.predecessor() => myCollection.index(before: myIndex)  
myIndex.advance(by: …) => myCollection.index(myIndex, offsetBy: …)  

 

(下面的模块除非是本身手动建立Range对象,不然我认为没有多大做用)

一方面,Range已经被划分为不少的类型。Range, ClosedRange, CountableRange, and CountableClosedRange.ClosedRange如今包括ranges扩宽了最大值类型(0...Int8.max).Range和ClosedRange 已经不能迭代了。他们如今须要一个可比较的对象做为他们的结合(因此你能够建立Range<String>)

学习更多的关于这个变化,请点击这里

OC的id已经被导入做为Swift的Any 类型

引用苹果的话是:

Since ‘id’ now imports as ‘Any’ rather than ‘AnyObject’, you may see errors where you were previously performing dynamic lookup on ‘AnyObject’.

因为id类型被当作了Any类型而不是AnyObject,因此你可能会看到一些错误当你先前查找AnyObject的动态类型时候。

学习更多的关于这个变化,请点击这里

一些很小的改变(你也许都没有注意到)

可选的操做符比较已经被移除

如今nil类型时能够比较的。案例:[3,nil,1,2].sorted()  // return [nil,1,2,3]

如今你须要解包可选类型在你比较以前(以下):

 

// Before
let a: Int = 4  
let b: Int? = 5  
if a > b { ... }  
   
// After  
guard let b = b, a > b else { ... }  
// or  
if let b = b {  
if a > b { ... }  
}  
// or  
if let b = b, a > b { ...}  

这也许是一件好事,可是可能拆除你的单元测试

学习更多的关于这个变化,请点击这里

 

闭包的参数名字和标签

不少的闭包参数的名字已经被重命名或者已经做为了可选

例如:

// before
words.sort(isOrderedBefore: >)  
let sum = measurements.reduce(0, combine: +)  
   
// after  
words.sort(by: >)  
let sum = measurements.reduce(0, +)  

 

flattern 重命名为joined

学习更多的关于这个变化,请点击这里

处理UnsafePointer<T>

非对象的指针类型为空行使用可选类型表示

学习更多的关于这个变化,请点击这里

Rounding floating (四舍五入浮点值是一个值的责任,如今)

之前咱们使用全局的C函数floor和ceil去四舍五入一个浮点值类型。这些函数仍然可使用可是已经考虑呗废弃。

所以咱们应该采用以下方式:

(4.4).rounded() // == 4.0
(4.5).rounded() // == 5.0  
(4.0).rounded(.up) // == 4.0  
(4.9).rounded(.down) // == 4.0  
(4.0).rounded(.down) // == 4.0  

 

这里还有另外的rounding的规则,以下:

  1. toNearestOrAwayFromZero
  2. toNearestOrEven
  3. towardZero
  4. awayFromZero

学习更多的关于这个变化,请点击这里

泛型类型的别名(Generic type aliases)

学习更多的关于这个变化,请点击这里

操做符的声明有了语法的改变

// Before
infix operator <> { precedence 100 associativity left }  
   
// After  
precedencegroup ComparisonPrecedence {  
associativity: left  
higherThan: LogicalConjunctionPrecedence  
}  
infix operator <> : ComparisonPrecedence  

 

学习更多的关于这个变化,请点击这里

OC的常量如今有了Swift类型

咱们再也不使用名字字符串做为OC的内在操做符

// Before
// HealthKit has the following strings:  
HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMassIndex;  
HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyFatPercentage;  
HK_EXTERN NSString * const HKQuantityTypeIdentifierHeight;  
HK_EXTERN NSString * const HKQuantityTypeIdentifierBodyMass;  
HK_EXTERN NSString * const HKQuantityTypeIdentifierLeanBodyMass;  
// They were previously imported as swift Strings  
   
// After  
// Instead of importing this as a string, Swift will import this like so:  
enum HKQuantityTypeIdentifier : String {  
case BodyMassIndex  
case BodyFatPercentage  
case Height  
case BodyMass  
case LeanBodyMass  
}  

 

学习更多的关于这个变化,请点击这里

这些东西可能过小你根本没有注意到

NSError 已经提供了桥梁

// Before

catch let error as AVError where error == .diskFull {

 

 

 
// AVError is an enum, so one only gets the equivalent of the code.  
// There is no way to access the localized description (for example) or  
// any other information typically stored in the ``userInfo`` dictionary.  
}  
   
// or  
catch let error as NSError where error._domain == AVFoundationErrorDomain && error._code == AVFoundationErrorDomain.diskFull.rawValue {  
// okay: userInfo is finally accessible, but still weakly typed  
}  
   
// And in usage:  
catch let error as NSError where error._domain = AVFoundationErrorDomain {  
if let time = error.userInfo[AVErrorTimeKey] as? CMTime {  
// ...  
}  
}  
   
// After  
catch let error as AVError {  
if let time = error.time {  
// ...  
}  
}  

 

学习更多的关于这个变化,请点击这里

nulTerminatedUTF8CString 重命名为utf8CString

学习更多的关于这个变化,请点击这里

移除了字符串的UnicodeScalar重复的初始化方法

学习更多的关于这个变化,请点击这里

Failable UnicodeScalar初始化如今返回的是可选类型

学习更多的关于这个变化,请点击这里

元组不在撒泼

// No longer allowed
func foo(a: Int, b: Int) {}  
let x = (1, b: 2)  
foo(x)  

学习更多的关于这个变化,请点击这里

 

没有了currying func声明的语法

// Before:
func curried(x: Int)(y: String) -> Float {  
return Float(x) + Float(y)!  
}  
   
// After:  
func curried(x: Int) -> (String) -> Float {  
return {(y: String) -> Float in  
return Float(x) + Float(y)!  
}  
}  

学习更多的关于这个变化,请点击这里

 

上面已经列举了因此的Swift3的变化?

显然不是。

这里还有一些意见仍然在省查中,些许意见已经被推迟到3.x。我也选择了一些我认为很是小的不包括在一些附加或者改变。像removal和merger这些不常用的API

此外,我尚未必要更深层次的研究任何一个变化,而是对于每个变化选择一些更高层次的审查。

有一些变化会在他们的范围内发生连锁反应。若是你对这个特殊的变化感兴趣的话,你应该看看SwiftEVO工程

Changes under active review / awaiting review for this release

  1. Add sequence-based initializers and merge methods to Dictionary
  2. Allow using optional binding to upgrade self from a weak to strong reference
  3. Add AnyHashable to standard library

Changes deferred to a 3.x release

  1. Rotate algorithm
  2. Removal of .self
  3. Allow Swift types to provide custom Obj-C representations
  4. Remove bridging conversion behavior from dynamic casts
  5. Rationalizing sequence end-operation names

Bonus:

Things I’m sure we’re all glad were rejected:

  1. Removal of where from the Swift language
  2. Require self to access instance members
  3. Removal of access modifiers from extensions
相关文章
相关标签/搜索