您的位置:首页 > 移动开发 > Swift

Swift 3那些不同以往的特性

2017-03-27 14:35 183 查看
原文:http://www.jianshu.com/p/5d911fae5b2f

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
开发者可能会因为
var
inout
而标的疑惑。所以最新的版本移除了方法参数中的
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)
这句话,
button
selector
是字符串,如果写的类型错了,能够编译通过,但是会在运行的时候崩溃。因为没有可以响应的方法。

为了解决这个潜在的问题,
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
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: