Swift 3那些不同以往的特性

由于Swift是开源的,所以关于这门语言所有的更新内容可以从GitHub上找到详细的解释。这是相关的内容更新

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

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

++和--操作符

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

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

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

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

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

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

以前可以写:

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

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

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

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

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

移除方法参数的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
}

算法比较简单,

Swift3中不运行设置方法参数作为变量,因为Swift开发者可能会因为varinout而标的疑惑。所以最新的版本移除了方法参数中的var

因此,用Swift3中的语法,达到这样的目的需要用不同的方法,比如需要去保存方法参数作为本丢变量。

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
}

扩展方法参数的形式

方法参数列表是以元组的形式,所以可以使用元组来调用函数,只要元组的结构和方法参数的结构一样,用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 {

...

}

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

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)这句话,buttonselector是字符串,如果写的类型错了,能够编译通过,但是会在运行的时候崩溃。因为没有可以响应的方法。

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

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

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))

从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)

通过Foundation中的类从文件中读取json数据,中间用到了NSBundle -> NSURL -> NSData -> NSJSONSerialization.

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)

纯手写码字有点累,下面还是直接给代码。

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

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")
}

枚举

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

比如:

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

关键字@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详细更新列表

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容