Swift3.0前瞻


2016/8/23 iOS swift

在 WWDC16 上苹果公布了 Swift3.0,新的变化几乎会让你的代码处处报错,但正是借助于苹果这种追求极致的精神,Swift 才会发展的如此迅速,下面对 Swift3.0 带来的变化稍作总结。

基本语法

  1. 调用函数时首个参数必须指定参数名;

在 Swift3.0 中不管是函数还是方法从第一个参数开始必须指定参数名(也可以使用 _ 省略参数)

func sum(num1: Int, num2: Int) -> Int {
    return num1 + num2
}
sum(num1: 1, num2: 2)
1
2
3
4
  1. 函数参数取消可变类型;
// func increase(var a: Int) {
//   a += 1
// }
// 上面的写法会报错,可改为
func increase(a: Int) {
    var a = a
    a += 1
}
1
2
3
4
5
6
7
8
  1. inout 参数修饰改放到参数类型前面;
// func increase(inout a: Int) {
//   a += 1
// }
// 上面的写法会报错,可改为
func increase( a:inout Int) {
    a += 1
}
1
2
3
4
5
6
7
  1. 必须接受或者处理函数返回值;

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
  1. 隐式可选类型和其他类型运算后获得可选类型而不是隐式可选类型;
let a: Int! = 1
// 此时强制解包
let b = a + 1
// 注意此时c是Int? 在之前版本中c是Int!
let c = a
1
2
3
4
5
  1. 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
  1. 定义协议中可选方法必须使用 @objc 来修饰;
@objc protocol MyProtocol {
    // old: optional func func1()
    @objc optional func func1()
    func func2()
}
1
2
3
4
5
  1. 取消 ++-- 操作符;
  2. 取消 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

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

去 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

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

新浮点协议

Float、Double、CGFloat 使用了新的协议,提供 IEEE-754 标准的属性和方法;

let a = 2 * Float.pi // old: let a = 2 * M_PI
let b = 2.0 * .pi // 注意前面是浮点型,后面可以省略Float
1
2

最后有必要提一下,之前有传闻说 Swift3.0 的语法和 API 都会稳定并且向上兼容,但是 WWDC 上官方证实这可能要到 Swift4 才能实现。但是过早的固定语法和 API 对于 Swift 的发展也不一定是好事,毕竟新特性的加入、更好的语法优化才能让 Swift 越来越好,更何况 Apple 提供了迁移工具也大大减少了迁移工作量。

上次更新: 10/24/2019, 12:39:39 AM