在 WWDC16 上苹果公布了 Swift3.0,新的变化几乎会让你的代码处处报错,但正是借助于苹果这种追求极致的精神,Swift 才会发展的如此迅速,下面对 Swift3.0 带来的变化稍作总结。
基本语法
- 调用函数时首个参数必须指定参数名;
在 Swift3.0 中不管是函数还是方法从第一个参数开始必须指定参数名(也可以使用 _
省略参数)
func sum(num1: Int, num2: Int) -> Int {
return num1 + num2
}
sum(num1: 1, num2: 2)
1
2
3
4
2
3
4
- 函数参数取消可变类型;
// func increase(var a: Int) {
// a += 1
// }
// 上面的写法会报错,可改为
func increase(a: Int) {
var a = a
a += 1
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- inout 参数修饰改放到参数类型前面;
// func increase(inout a: Int) {
// a += 1
// }
// 上面的写法会报错,可改为
func increase( a:inout Int) {
a += 1
}
1
2
3
4
5
6
7
2
3
4
5
6
7
- 必须接受或者处理函数返回值;
Swift3.0 中函数返回值必须要接收否则会警告,返回值没用时可以使用 _
接收来忽略,当然也可以增加 @discardableResult
声明,告诉编译器此方法不用接收返回值;
struct Caculator {
func sum(a: Int,b: Int) -> Int {
return a + b
}
@discardableResult
func func1(a: Int,b: Int) ->Int {
return a - b + 1
}
}
let ca = Caculator()
// 此处会警告
ca.sum(a: 1, b: 2)
// 使用"_"接收无用返回值
let _ = ca.sum(a: 1, b: 2)
// 添加@discardableResult声明后不会警告
ca.func1(a: 1, b: 2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- 隐式可选类型和其他类型运算后获得可选类型而不是隐式可选类型;
let a: Int! = 1
// 此时强制解包
let b = a + 1
// 注意此时c是Int? 在之前版本中c是Int!
let c = a
1
2
3
4
5
2
3
4
5
selector
格式改变为#selector(method(param1: param2:))
;
class MyClass {
@objc func sum(a: Int,b: Int) -> Int {
return a + b
}
func func1(){
let _ = #selector(sum(a: b:))
}
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- 定义协议中可选方法必须使用
@objc
来修饰;
@objc protocol MyProtocol {
// old: optional func func1()
@objc optional func func1()
func func2()
}
1
2
3
4
5
2
3
4
5
- 取消
++
、--
操作符; - 取消 C 语言风格
for
循环;
// for var i = 0 ;i < 10 ; i += 1 {
// debugPrint(i)
// }
// 上面写法会报错,改为如下
for i in 0 ..< 10 {
debugPrint(i)
}
1
2
3
4
5
6
7
2
3
4
5
6
7
SDK 类库
早起 Swift 为了保证 OC 开发人员顺利过渡到 Swift,很多类库和方法命名都尽量和 OC 保持一致,但是作为一门新语言 Swift 需要不断做出改变,这其中包括重新导入 Foundation 消除类型前缀、方法名去重、函数和方法去 C 风格等等。
命名方式
// 1.去掉前缀
let url1 = URL(string: "www.cmjstudio.com")
let isFileURL = url1?.isFileURL // old:url1.fileURL 现在更加注重语意
let data1 = Data()
// 2.方法名使用动词, 其他词作为参数或移除
var array1 = [1,2,3]
array1.append(contentsOf: [4,5,6]) // old:array1.appendContentsOf([4,5,6])
array1.remove(at: 0) // old:array1.removeAtIndex(0)
// 3.不引起歧义的情况下尽量消除重复
let color1 = UIColor.red() // old:var color1 = UIColor.redColor()
// 4.枚举成员首字母变成小写
let label1 = UILabel()
label1.textAlignment = .center // old:label1.textAlignment = .Center
// 5.去掉按钮Normal状态
let btn1 = UIButton()
btn1.setTitle("hello", for: UIControlState()) // 相当于Normal状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
去 C 风格
Swift 初期很多类库的引入依然保持 OC 风格,但是由于 OC 根出自 C 语言,因此很多操作是 C 语言的函数形式,Swift3.0 之后全局函数将会变成某些类型的方法,某些常量定义将以某个枚举类型的成员来表示;
let rect1 = CGRect(x: 0, y: 0, width: 100, height: 100)
// 下面的代码会报错,3.0将废除这种类C风格
// old:let rect1 = CGRectMake(0, 0, 100, 100)
if let context1 = UIGraphicsGetCurrentContext() {
CGContext.fillPath(context1) // old:CGContextFillPath(context1!)
}
// GCD改变
let queue = DispatchQueue(label: "myqueue")
queue.async {
debugPrint("hello world!")
}
// old:
// let queue = dispatch_queue_create("myqueue", nil)
// dispatch_async(queue) {
// debugPrint("hello world!")
// }
// 相关常量定义被移到枚举内部
NotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: UserDefaults.didChangeNotification, object: nil)
//old:NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: NSUserDefaultsDidChangeNotification, object: nil)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
API 变化
let array1 = [1,2,3]
let next = array1.index(after: 0) // old:let start = array1.startIndex let next = start.successor()
// 增加的新方法
let first = array1.first { (element) -> Bool in
element > 1
}
let r = Range(0..<3) //old: let _ = NSRange(location: 0, length: 3)
// 下面的代码在控制器中执行,用于遍历当前view及其父视图
for subview in sequence(first: self.view, next: { $0?.superview }) {
debugPrint(subview)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
新浮点协议
Float、Double、CGFloat 使用了新的协议,提供 IEEE-754
标准的属性和方法;
let a = 2 * Float.pi // old: let a = 2 * M_PI
let b = 2.0 * .pi // 注意前面是浮点型,后面可以省略Float
1
2
2
最后有必要提一下,之前有传闻说 Swift3.0 的语法和 API 都会稳定并且向上兼容,但是 WWDC 上官方证实这可能要到 Swift4 才能实现。但是过早的固定语法和 API 对于 Swift 的发展也不一定是好事,毕竟新特性的加入、更好的语法优化才能让 Swift 越来越好,更何况 Apple 提供了迁移工具也大大减少了迁移工作量。