iOS开发 Swift3新特性

苹果集成Swift 3到Xcode 8 Beta在WWDC将于今年晚些时候发布的最终版本.这是该语言的第一个版本,它是开源的,在Mac OS X和Linux上都能使用.如果你从去年十二月开始迅速的进化过程,甚至已经在IBM沙盒中玩过,你知道有很多变化.如果你编译你的应用程序在Xcode 8,它会破坏你的代码.

Swift 3改变可以分为两个大的部分

  • 1.移除在Swift 2.2中弃用的方法
  • 2.语言更加安全,优雅(正确的废话)

1.++和--操作符

自增自减操作符是从C语音搬过来的,非常快捷来增加或者减少1.

var i = 0
i ++
++ i
i --
--i

对于初学者而言可能有些奇怪,所以被移除了.使用+=或者-=来赋值操作.当然也可以通过操作符重载来实现上述的功能.

var i = 0
i += 1
i -= 1
var i = 0
i = i + 1
i = i - 1

2.C语言风格的循环已经成为历史

大多数语言都是使用C语言风格的操作符来表示循环.移除这个操作意味着以后就不能用了.因为用for-in操作完全可以替代的。

以前这样写:

for (i = 1; i <= 10; i++) {
  print(i)
}

在swift 3中,不允许这样的写法,用...表示的范围

for i in 1...10 {
  print(i)
}

你也可以用闭包和快捷参数来使用for-each

(1...10).forEach { (i) in
  print(i)
}

3.移除方法参数的var声明

方法参数通常被定义为常量,因为不需要在函数内部修改它,然后有些情况下当把声明作为变量的时候可能会更加方便.在Swift2中,可以通过关键字var标记一个方法参数作为变量,一旦方法参数用var修饰,将会创建一份对于参数的Copy.所以你可以在函数内部修改它的值.

下面一个例子,用于求两个数的最大公约数:

func gcd(var a: Int, var b: Int) -> Int {
  if (a == b) {
    return a
  }
  repeat {
    if (a > b) {
      a = a - b
    } else {
      b = b - a
    }
  } while (a != b)
  return a
}

算法比较简单

func gcd(a: Int, b: Int) -> Int {
  if (a == b) {
    return a
  }
  var c = a
  var d = b
  repeat {
    if (c > d) {
      c = c - d
    } else {
      d = d - c
    }
  } while (c != d)

  return c
}

在Swift3中不运行设置方法参数作为变量,因为Swift开发者可能会因为var和inout而标的疑惑.所以最新的版本移除了方法参数中的var.因此,用Swift3中的语法,达到这样的目的需要用不同的方法,比如需要去保存方法参数作为本丢变量.

4.扩展方法参数的形式

方法参数列表是以元组的形式,所以可以使用元组来调用函数,只要元组的结构和方法参数的结构一样,用gcd()做一个例子:

可以这样调用:gcd(8, b: 12)

或者可以:

let number = (8, b: 12)
gcd(number)

正如你所见,你不需要给第一个参数具体化在Swift2,然后你不得不在调用方法的时候具体化第二个参数.

这样的语法对于初学者而言具有迷惑性,所以使用标准的形式,在Swift3中,如下调用:gcd(a: 8, b: 12)

你不得不给第一个参数精确地修饰符,如果不这样做,Xcode 8直接就会报错

可能看到这样的改变,会觉得那我以前的代码如何兼容呢,为了兼容以前的,苹果推出一种方式来解决.如下:

func gcd(_ a: Int, b: Int) -> Int {
    //
}

这样改变了方法名称之后,就能兼容之前调用的方式了。

5.Seletors 作为字符串不在起作用

常见的我们在创建一个button之后,然后会给它加上点击事件,比如:

//1
import UIKit
import XCPlayground

// 2
class Responder: NSObject {

  func tap() {
    print("Button pressed")
  }
}
let responder = Responder()

// 3
let button = UIButton(type: .System)
button.setTitle("Button", forState: .Normal)
button.addTarget(responder, action: "tap", forControlEvents: .TouchUpInside)
button.sizeToFit()
button.center = CGPoint(x: 50, y: 25)

// 4
let frame = CGRect(x: 0, y: 0, width: 100, height: 50)
let view = UIView(frame: frame)
view.addSubview(button)
XCPlaygroundPage.currentPage.liveView = view

重点看一下button.addTarget(responder, action: "tap", forControlEvents: .TouchUpInside)这句话,button的selector是字符串,如果写的类型错了,能够编译通过,但是会在运行的时候崩溃.因为没有可以响应的方法.

为了解决这个潜在的问题,Swift3用#selector()关键字替换了字符串类型的selectors.这种方式可以让编译器在编译的时候,如果不存在这样的方法名就能直接报出编译错误,代码如下:

btton.addTarget(responder, action: #selector(Responder.tap), for: .touchUpInside)

6.Key-paths 作为字符串

和Seletors作为字符串不在起作用类似,只不过将这种特性运用到了KVC(键值编码)和KVO(观察者):

之前的方式:

class Person: NSObject {
  var name: String = ""

  init(name: String) {
    self.name = name
  }
}
let me = Person(name: "Cosmin")
me.valueForKeyPath("name")

如果me.valueForKeyPath("name")中不存在属性name,运行到这段代码必将崩溃.

在Swift3中就不用担心,Key-Path已经用#keyPath()代替.

如下:

class Person: NSObject {
  var name: String = ""

  init(name: String) {
    self.name = name
  }
}
let me = Person(name: "Cosmin")
me.value(forKeyPath: #keyPath(Person.name))

7.从Foundation类型中去掉NS前缀

提及NS前缀,大家应该知道是Next-Step的缩写吧.但是Swift毕竟是一门崭新的语言,所以从前缀上就能之前的习惯做了区分.可以看出,这也是未来Swift会大行其道的预兆.

比如之前:

let file = NSBundle.mainBundle().pathForResource("tutorials", ofType: "json")
let url = NSURL(fileURLWithPath: file!)
let data = NSData(contentsOfURL: url)
let json = try! NSJSONSerialization.JSONObjectWithData(data!, options: [])
print(json)

在Swift3中,前缀被移除,看起来更加优雅

let file = Bundle.main().pathForResource("tutorials", ofType: "json")
let url = URL(fileURLWithPath: file!)
let data = try! Data(contentsOf: url)
let json = try! JSONSerialization.jsonObject(with: data)
print(json)

8.M_PI vs .pi

之前:

let r =  3.0
let circumference = 2 * M_PI * r
let area = M_PI * r * r

之前是使用M_PI指代pi常量,Swift3中分别在Float,Double,CGFloat几种类型中指代了pi常量.

之后:

let r = 3.0
let circumference = 2 * Double.pi * r
let area = Double.pi * r * r

9.GCD

之前:

let queue = dispatch_queue_create("Swift 2.2", nil)
dispatch_async(queue) {
  print("Swift 2.2 queue")
}

之后:(通过对象的方式调用)

let queue = DispatchQueue(label: "Swift 3")
queue.async {
  print("Swift 3 queue")
}

10.枚举

Swift 3中将枚举case看起来像属性,所以使用小写的方式表示了系统的而一些枚举值:

比如:

.System becomes .system
.TouchUpInside becomes .touchUpInside
.FillStroke becomes .fillStroke
.CGColor becomes .cgColor

11.关键字@discardableResult

在Swift3中,如果没有使用方法的返回值,会报出警告.如下:


使用@discardableResult关键字取消警告

override func viewDidLoad() {
    super.viewDidLoad()

    printMessage(message: "Hello Swift 3!")
}

@discardableResult
func printMessage(message: String) -> String {
    let outputMessage = "Output : \(message)"
    print(outputMessage)

    return outputMessage
}

英文原文

Swift详细更新列表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值