Error[8]: Undefined offset: 50, File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 121
File: /www/wwwroot/outofmemory.cn/tmp/plugin_ss_superseo_model_superseo.php, Line: 473, decode(

概述Apple 在 WWDC 上已将 Swift 3 整合进了 Xcode 8 beta 中,并会在今年晚些时候发布 Swift 3 的正式版。这是 Swift 在开源和支持 Mac OS X 与 Linux 之后的首个版本。如果你在去年 11 月关注了 Swift 进化史 和已经启动的 IBM 沙盒 项目,那你应该知道 Swift 确实改动很多。甚至可以确定你在 Xcode 8 上根本无法编译既有项

Apple 在 WWDC 上已将 Swift 3 整合进了 Xcode 8 beta 中,并会在今年晚些时候发布 Swift 3 的正式版。这是 Swift 在开源和支持 Mac OS X 与 linux 之后的首个版本。如果你在去年 11 月关注了Swift 进化史和已经启动的IBM 沙盒项目,那你应该知道 Swift 确实改动很多。甚至可以确定你在 Xcode 8 上根本无法编译既有项目。

Swift 3 的改动归结下来主要有两点:

移除了在 Swift 2.2 就已经弃用的特性 语言现代化问题

让我们从移除特性讲起,毕竟这点能容易理解,而且在 Xcode 7.3 的时候我们遇到了相关警告。

++-- *** 作符

自增自减是来源于 C 的 *** 作符,作用是对变量直接进行+1-1的 *** 作:

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

然而,在我们要选择使用哪一种 *** 作符进行运算的时候,事情就变得复杂起来。无论是自增还是自减,都对应着两种写法:写在在变量之前,还是在变量之后。它们的底层实现其实都是有返回值的函数,是否使用返回值取决于对运算符的重载。

这可能会吓跑初学者,所以苹果移除了该特性——取而代之的是复合加法运算(+=)与减法运算(-=):

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

当然,你也可以使用普通的加法运算(+)与减法运算(-),虽然复合式运算符写起来要短一点:

i = i + 1i = i - 1

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读Chris Lattner 对移除++--的看法。

C 风格的 for 循环已成历史

其实自增自减运算符用得最多的地方,还是在 for 循环部分。移除该运算符意味着 for 循环的特性也随之远去了,因为在 for-in 的世界中,循环控制语句与范围限制用不上该 *** 作符。

如果你有一定编程背景,那么输出 1 到 100 的数,你可能会这样写:

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

在 Swift 3 中,已经不允许这种写法了,而应该写为(注意闭区间范围的写法):

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

或者,你也可以使用 for-each 加闭包的写法(更多循环相关信息请看这):

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

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读Erica Sadun 对移除 C 风格循环的看法。

var 移除函数参数的var标记

如果不需要在函数内部对参数进行修改的话,函数参数通常都定义为常量。然而,在某些情况下,定义成变量会更加合适。在 Swift 2 中,你可以用var关键字来将函数参数标记为变量。一旦参数用

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}
来标记,就会生成一份变量的拷贝,如此便能在方法内部对变量进行修改了。

下面是一个求两个数的最大公约数的例子(如果想到回到高中数学课堂再学习一遍,请移步):

a

这个算法的逻辑很简单:如果两个数相等,则返回其中一个的值。否则,做大小比较,大的数减去小的数之后,将差值赋值给大的数,然后再将两个数作比较,为止它们相等为止,最终返回其中一个的值。正如你所看到的,通过将bvar标记为变量,才能在函数体里对两个数进行修改。

Swift 3 不在允许开发者这样来将参数标记为变量了,因为开发者可能会在inoutvar纠结不已。所以最新的 Swift 版本中,就干脆移除了函数参数标记gcd的特性。

如此,想要用 Swift 3 来写上面的

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}
函数,就要另辟蹊径了。你需要在函数内部创建临时变量来存储参数:

var

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读决定移除的想法。

gcd() 函数参数标签的一致性

函数的参数列表底层实现其实是元组,所以只要元组结构和函数参数列表相同,你可以直接用元组来代替参数列表。就拿刚才的

gcd(8,b: 12)
函数来说,你可以这样调用:

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

你也可以这样调用:

gcd(a: 8,b: 12)

正如你所看到的,在 Swift 2 中,第一个参数无需带标签,而从第二个参数开始,就必须要带标签了。

这个语法对初学者来说可能会造成困惑,所以,要进行统一标签设计。在 Swift 3 中,函数的调用要像下面这样:

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

即使是第一个参数,也必须带上标签。如果不带,Xcode 8 会直接报错。

你对这修改的第一个反应可能是:「我哔!那我代码改动得多大啊!」是的,这简直是成吨的伤害。所以苹果又给出了一种不用给第一个参数带标签的解决方案。在第一个参数前面加上一个下划线:

但是这样做,事情又仿佛回到了原点——第一个参数不用带标签了。使用这种方式,应该能一定程度上降低 Swift 2 迁移到 Swift 3 上的痛苦。

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读函数标签一致性的一些想法。

// 1import UIKitimport XCPlayground // 2class Responder: NSObject {   func tap() {    print("button pressed")  }}let responder = Responder() // 3let 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) // 4let frame = CGRect(x: 0,y: 0,wIDth: 100,height: 50)let vIEw = UIVIEw(frame: frame)vIEw.addSubvIEw(button)XCPlaygroundPage.currentPage.liveVIEw = vIEw
Selector 不再允许使用 String

让我们来创建一个按钮,并给它添加一个点击事件(不需要界面支持,直接使用 playground 就行):

UIKit

让我们一步一步分析下上面的代码:

导入XCPlaygroundNSObject框架——需要创建一个按钮,并在 playground 的 assistant editor 中进行显示。

注意:你需要在 Xcode 菜单栏上的 VIEw -> Assistant Editor -> Show Assistant Editor 来开启 assistant editor。

创建点击的触发事件,能在用户点击按钮时,触发绑定的事件——这需要基类为

button.addTarget(responder,forControlEvents: .touchUpInsIDe)
,因为 selector 仅对 Objective-C 的方法有效。

声明按钮,并配置相关属性。

声明视图,给定合适的大小,将按钮添加到视图上,最后显示在 playground 的 assistant editor 中。

让我们来看下给按钮添加事件的代码:

#selecor()

这里按钮的 selector 还是写的字符串。如果字符串拼写错了,那程序会在运行时因找不到相关方法而崩溃。

为了解决编译期间的潜在问题,Swift 3 将字符串 selector 的写法改为了

button.addTarget(responder,action: #selector(Responder.tap),for: .touchUpInsIDe)
。这将允许编译器提前检查方法名的拼写问题,而不用等到运行时。

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读Doug Gregor 的观点。

以上就是关于移除特性的全部内容。接下来,让我们来看看语言现代化的一些亮点。

class Person: NSObject {  var name: String = ""   init(name: String) {    self.name = name  }}let me = Person(name: "Cosmin")me.valueForKeyPath("name")
不再是 String 的 key-path 写法

这个特性和上一个很相似,但是这是用在键值编码(KVC)与键值观察(KVO)上的:

Person

首先创建了me类,这是 KVC 的首要条件。然后用指定的构造器初始化一个name,最后通过 KVC 来修改[+++]。同样,如果 KVC 中的键拼写错误,这一切就白瞎了 总结

以上是内存溢出为你收集整理的Swift 3 新变化全部内容,希望文章能够帮你解决Swift 3 新变化所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

)
File: /www/wwwroot/outofmemory.cn/tmp/route_read.php, Line: 126, InsideLink()
File: /www/wwwroot/outofmemory.cn/tmp/index.inc.php, Line: 165, include(/www/wwwroot/outofmemory.cn/tmp/route_read.php)
File: /www/wwwroot/outofmemory.cn/index.php, Line: 30, include(/www/wwwroot/outofmemory.cn/tmp/index.inc.php)
Swift 3 新变化_app_内存溢出

Swift 3 新变化

Swift 3 新变化,第1张

概述Apple 在 WWDC 上已将 Swift 3 整合进了 Xcode 8 beta 中,并会在今年晚些时候发布 Swift 3 的正式版。这是 Swift 在开源和支持 Mac OS X 与 Linux 之后的首个版本。如果你在去年 11 月关注了 Swift 进化史 和已经启动的 IBM 沙盒 项目,那你应该知道 Swift 确实改动很多。甚至可以确定你在 Xcode 8 上根本无法编译既有项

Apple 在 WWDC 上已将 Swift 3 整合进了 Xcode 8 beta 中,并会在今年晚些时候发布 Swift 3 的正式版。这是 Swift 在开源和支持 Mac OS X 与 linux 之后的首个版本。如果你在去年 11 月关注了Swift 进化史和已经启动的IBM 沙盒项目,那你应该知道 Swift 确实改动很多。甚至可以确定你在 Xcode 8 上根本无法编译既有项目。

Swift 3 的改动归结下来主要有两点:

移除了在 Swift 2.2 就已经弃用的特性 语言现代化问题

让我们从移除特性讲起,毕竟这点能容易理解,而且在 Xcode 7.3 的时候我们遇到了相关警告。

++-- *** 作符

自增自减是来源于 C 的 *** 作符,作用是对变量直接进行+1-1的 *** 作:

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

然而,在我们要选择使用哪一种 *** 作符进行运算的时候,事情就变得复杂起来。无论是自增还是自减,都对应着两种写法:写在在变量之前,还是在变量之后。它们的底层实现其实都是有返回值的函数,是否使用返回值取决于对运算符的重载。

这可能会吓跑初学者,所以苹果移除了该特性——取而代之的是复合加法运算(+=)与减法运算(-=):

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

当然,你也可以使用普通的加法运算(+)与减法运算(-),虽然复合式运算符写起来要短一点:

i = i + 1i = i - 1

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读Chris Lattner 对移除++--的看法。

C 风格的 for 循环已成历史

其实自增自减运算符用得最多的地方,还是在 for 循环部分。移除该运算符意味着 for 循环的特性也随之远去了,因为在 for-in 的世界中,循环控制语句与范围限制用不上该 *** 作符。

如果你有一定编程背景,那么输出 1 到 100 的数,你可能会这样写:

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

在 Swift 3 中,已经不允许这种写法了,而应该写为(注意闭区间范围的写法):

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

或者,你也可以使用 for-each 加闭包的写法(更多循环相关信息请看这):

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

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读Erica Sadun 对移除 C 风格循环的看法。

var 移除函数参数的var标记

如果不需要在函数内部对参数进行修改的话,函数参数通常都定义为常量。然而,在某些情况下,定义成变量会更加合适。在 Swift 2 中,你可以用var关键字来将函数参数标记为变量。一旦参数用

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}
来标记,就会生成一份变量的拷贝,如此便能在方法内部对变量进行修改了。

下面是一个求两个数的最大公约数的例子(如果想到回到高中数学课堂再学习一遍,请移步):

a

这个算法的逻辑很简单:如果两个数相等,则返回其中一个的值。否则,做大小比较,大的数减去小的数之后,将差值赋值给大的数,然后再将两个数作比较,为止它们相等为止,最终返回其中一个的值。正如你所看到的,通过将bvar标记为变量,才能在函数体里对两个数进行修改。

Swift 3 不在允许开发者这样来将参数标记为变量了,因为开发者可能会在inoutvar纠结不已。所以最新的 Swift 版本中,就干脆移除了函数参数标记gcd的特性。

如此,想要用 Swift 3 来写上面的

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}
函数,就要另辟蹊径了。你需要在函数内部创建临时变量来存储参数:

var

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读决定移除的想法。

gcd() 函数参数标签的一致性

函数的参数列表底层实现其实是元组,所以只要元组结构和函数参数列表相同,你可以直接用元组来代替参数列表。就拿刚才的

gcd(8,b: 12)
函数来说,你可以这样调用:

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

你也可以这样调用:

gcd(a: 8,b: 12)

正如你所看到的,在 Swift 2 中,第一个参数无需带标签,而从第二个参数开始,就必须要带标签了。

这个语法对初学者来说可能会造成困惑,所以,要进行统一标签设计。在 Swift 3 中,函数的调用要像下面这样:

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

即使是第一个参数,也必须带上标签。如果不带,Xcode 8 会直接报错。

你对这修改的第一个反应可能是:「我哔!那我代码改动得多大啊!」是的,这简直是成吨的伤害。所以苹果又给出了一种不用给第一个参数带标签的解决方案。在第一个参数前面加上一个下划线:

但是这样做,事情又仿佛回到了原点——第一个参数不用带标签了。使用这种方式,应该能一定程度上降低 Swift 2 迁移到 Swift 3 上的痛苦。

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读函数标签一致性的一些想法。

// 1import UIKitimport XCPlayground // 2class Responder: NSObject {   func tap() {    print("button pressed")  }}let responder = Responder() // 3let 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) // 4let frame = CGRect(x: 0,y: 0,wIDth: 100,height: 50)let vIEw = UIVIEw(frame: frame)vIEw.addSubvIEw(button)XCPlaygroundPage.currentPage.liveVIEw = vIEw
Selector 不再允许使用 String

让我们来创建一个按钮,并给它添加一个点击事件(不需要界面支持,直接使用 playground 就行):

UIKit

让我们一步一步分析下上面的代码:

导入XCPlaygroundNSObject框架——需要创建一个按钮,并在 playground 的 assistant editor 中进行显示。

注意:你需要在 Xcode 菜单栏上的 VIEw -> Assistant Editor -> Show Assistant Editor 来开启 assistant editor。

创建点击的触发事件,能在用户点击按钮时,触发绑定的事件——这需要基类为

button.addTarget(responder,forControlEvents: .touchUpInsIDe)
,因为 selector 仅对 Objective-C 的方法有效。

声明按钮,并配置相关属性。

声明视图,给定合适的大小,将按钮添加到视图上,最后显示在 playground 的 assistant editor 中。

让我们来看下给按钮添加事件的代码:

#selecor()

这里按钮的 selector 还是写的字符串。如果字符串拼写错了,那程序会在运行时因找不到相关方法而崩溃。

为了解决编译期间的潜在问题,Swift 3 将字符串 selector 的写法改为了

button.addTarget(responder,action: #selector(Responder.tap),for: .touchUpInsIDe)
。这将允许编译器提前检查方法名的拼写问题,而不用等到运行时。

延伸阅读:如果你想要了解更多该变更背后的故事,请阅读Doug Gregor 的观点。

以上就是关于移除特性的全部内容。接下来,让我们来看看语言现代化的一些亮点。

class Person: NSObject {  var name: String = ""   init(name: String) {    self.name = name  }}let me = Person(name: "Cosmin")me.valueForKeyPath("name")
不再是 String 的 key-path 写法

这个特性和上一个很相似,但是这是用在键值编码(KVC)与键值观察(KVO)上的:

Person

首先创建了me类,这是 KVC 的首要条件。然后用指定的构造器初始化一个name,最后通过 KVC 来修改。同样,如果 KVC 中的键拼写错误,这一切就白瞎了 总结

以上是内存溢出为你收集整理的Swift 3 新变化全部内容,希望文章能够帮你解决Swift 3 新变化所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1090483.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存