swift程序员iOS Developer

Swift 3.0到底有什么新东东呢?

2016-05-24  本文已影响8202人  刘铭iOS

Swift 3.0 几乎改变了一切,如果直接拿Swift 2.2的代码在3.0的环境下构建则一定会报错,我们一定要做出相应的改变。

在这篇文章中,我将尽我所能,利用代码样例给大家解释Swift 3.0最重要(要命)的改变,希望大家能够做好升级Swift 3.0 的准备。Swift 3.0的改变不仅仅是我下面的这个列表,但是列表中的每一项都是对你的一个巨大的打击。

预先警告#1:Swift 3.0 仍处于开发阶段。

预先警告#2:Swift 3.0 会有很多很多的变化,其中一些可能会在细微之处。然而,我们希望这些变化是一次性的。为了使Swift可以在未来几年更好的发展,在以后的版本更新中改变应该的显著变小。

预先警告#3:有些Swift 2.2的东西已经过时了,并且被删除了。这包括++,--,C风格的for循环,元组语法等等。

所有函数参数都有标签,除非你坚持

在Swift 2.0 中调用函数和方法已经做出了改变,在3.0中又发生了变化,而这一次的改变则是彻底的、抛弃旧我的!在Swift 2.0及以前的方法名是不需要为第一个参数设置标签的,所以第一个参数名称通常会内置到方法名称的最后,比如:

names.indexOf("Taylor")

"Taylor".writeToFile("filename", atomically:true, encoding:NSUTF8StringEncoding)

SKAction.rotateByAngle(CGFloat(M_PI_2), duration:10)

UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)

overridefuncnumberOfSectionsInTableView(tableView:UITableView) ->IntfuncviewForZoomingInScrollView(scrollView:UIScrollView) ->UIView?

NSTimer.scheduledTimerWithTimeInterval(0.35, target:self, selector:#selector(createEnemy), userInfo:nil, repeats:true)

在Swift 3.0中所有的所有的标签都是必须的,这也就代表着方法名不再含有参数的部分。在实际操作中,就是方法名的最后一部分被移入到了括号之中。

names.indexOf("Taylor")

names.index(of:"Taylor")

"Taylor".writeToFile("filename", atomically:true, encoding:NSUTF8StringEncoding)

"Taylor".write(toFile:"somefile", atomically:true, encoding:NSUTF8StringEncoding)

SKAction.rotateByAngle(CGFloat(M_PI_2), duration:10)

SKAction.rotate(byAngle:CGFloat(M_PI_2), duration:10)

UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)

UIFont.preferredFont(forTextStyle: UIFontTextStyleSubheadline)

overridefuncnumberOfSectionsInTableView(tableView:UITableView) ->IntoverridefuncnumberOfSections(intableView:UITableView) ->IntfuncviewForZoomingInScrollView(scrollView:UIScrollView) ->UIView?

funcviewForZooming(inscrollView:UIScrollView) ->UIView?

NSTimer.scheduledTimerWithTimeInterval(0.35, target:self, selector:#selector(createEnemy), userInfo:nil, repeats:true)

NSTimer.scheduledTimer(timeInterval:0.35, target:self, selector:#selector(createEnemy), userInfo:nil, repeats:true)

但,还是有一些连锁反应的方法:当我们连接到框架的时候,比如UIKit,这些方法希望在 Swift 3.0 中还是沿用旧有的“无第一参数名”的规则。在Swift 2.2 中:

overridefuncviewWillAppear(animated:Bool)

overridefunctableView(tableView:UITableView, numberOfRowsInSection section:Int) ->IntoverridefuncdidMoveToView(view:SKView)

overridefunctraitCollectionDidChange(previousTraitCollection:UITraitCollection?)

functextFieldShouldReturn(textField:UITextField) ->Bool

在 Swift 3.0中,他们都需要在第一参数前使用下划线标识它们使用ObjC代码,而不使用参数标签。

overridefuncviewWillAppear(_animated:Bool)

overridefunctableView(_tableView:UITableView, numberOfRowsInSection section:Int) ->Int

overridefuncdidMoveToView(_view:SKView)

overridefunctraitCollectionDidChange(_previousTraitCollection:UITraitCollection?)

functextFieldShouldReturn(_textField:UITextField) ->Bool

忽略不必要的词

当Swift在2015年12月被开源的时候,全新的API指导方针包含了三个要命的词:“忽略 不必要 词语”,它引入了Swift 3.0 中另一个巨大的改变,因为在方法名中那些根本没有必要出现的词语将被移去。让我们看下面的这些swift 2.2中的代码:

letblue = UIColor.blueColor()

letmin = numbers.minElement()

attributedString.appendAttributedString(anotherString)

names.insert("Jane", atIndex:0)

UIDevice.currentDevice()

能看出代码中的问题吗?当我们使用UIColor的时候,blue当然是一个颜色,所以使用blueColor是多余的。当我们添加一个属性字符串到另一个的时候,这两个东东一定都是字符串,而不可能另一个是“大象”对吧!所以,相同的代码在Swift 3.0中就是:

letblue = UIColor.blue()

letmin = numbers.min()

attributedString.append(anotherString)

names.insert("Jane", at:0)

UIDevice.current()

正如你看到的,这个改变让方法名称更短了。

这种改变在字符串的操作上效果显著,对比下面的代码,你会发现Swift 2.2和Swift 3.0之间,我们写入的代码真是少了。

"  Hello  ".stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet())

"  Hello  ".trimmingCharacters(in: .whitespacesAndNewlines())

"Taylor".containsString("ayl")

"Taylor".contains("ayl")

"1,2,3,4,5".componentsSeparatedByString(",")

"1,2,3,4,5".componentsSeparated(by:",")

myPath.stringByAppendingPathComponent("file.txt")

myPath.appendingPathComponent("file.txt")

"Hello, world".stringByReplacingOccurrencesOfString("Hello", withString:"Goodbye")

"Hello, world".replacingOccurrences(of:"Hello", with:"Goodbye")

"Hello, world".substringFromIndex(7)

"Hello, world".substring(from:7)

"Hello, world".capitalizedString

"Hello, world".capitalized

注意:capitalized 仍然是一个属性,但是lowercaseString 和 uppercaseString 改头换面成为方法 lowercased() 和 uppercased()了。

还有一个Swift 3.0的方法是下面这样:

dismiss(animated:true, completion:nil)

你可能会想,我们要dismiss什么呢?Swift 3.0是既要添加第一参数的标签,又要删除不必要的词,所以上面的代码实际是Swift 2.2中的

dismissViewControllerAnimated(true, completion:nil)

具有同样效果的还有prepareForSegue方法,在Swift 3.0 中它变成了这样:

overridefuncprepare(forsegue:UIStoryboardSegue, sender:AnyObject?)

对于枚举和属性,驼峰大写前缀被替换成了驼峰小写前缀

虽然与语法没有什么关系,但是我们对于类、结构、属性和枚举,始终遵循着一个约定:类、结构和枚举使用驼峰大写前缀,属性和参数名称使用驼峰小写前缀。这个约定也有例外,使用NSURLRequest(URL: someURL) 创建NSURLRequest对象的时候,参数就是大写URL。Swift 3重写了该方法为NSURLRequest(url: someURL) ,也意味着我们将会使用webView.request?.url?.absoluteString方式来读取web view的URL。

还有一些是在属性部分,比如说CGColor或CIColor。是的,现在它将会变成cgColor和ciColor。

letred = UIColor.red().cgColor

这种变化确实提高了编码的一致性:所有的属性和参数应该都是以小写开始,没有例外!

同时,枚举也在发生着改变,从驼峰大写前缀改为驼峰小写前缀。这意味着:枚举是一个数据类型,但是枚举值更接近属性。然而,这意味着苹果的枚举现在都是小写了。

UIInterfaceOrientationMask.Portrait// old

UIInterfaceOrientationMask.portrait// new

NSTextAlignment.Left// old

NSTextAlignment.left// new

SKBlendMode.Replace// old

SKBlendMode.replace// new

Swift 引入 C 函数

Swift 3引入C函数的属性。比如,所有以CGContext开头的函数现在都被映射为CGContext对象上的属性方法,这样我们就可以不再使用令我们非常痛苦的CGContextSetFillColorWithColor()函数了。

swift 2.2中的代码:

letctx = UIGraphicsGetCurrentContext()

letrectangle = CGRect(x:0, y:0, width:512, height:512)

CGContextSetFillColorWithColor(ctx, UIColor.redColor().CGColor)

CGContextSetStrokeColorWithColor(ctx, UIColor.blackColor().CGColor)

CGContextSetLineWidth(ctx,10)

CGContextAddRect(ctx,rectangle)

CGContextDrawPath(ctx, .FillStroke)

UIGraphicsEndImageContext()

在Swift 3.0中CGContext被作为对象处理,我们可以直接调用方法了。

ifletctx = UIGraphicsGetCurrentContext() {

letrectangle = CGRect(x:0, y:0, width:512, height:512)

ctx.setFillColor(UIColor.red().cgColor)

ctx.setStrokeColor(UIColor.black().cgColor)

ctx.setLineWidth(10)

ctx.addRect(rectangle)

ctx.drawPath(using: .fillStroke)

UIGraphicsEndImageContext()

}

注意:不管是Swift 2.2还是Swift 3.0 UIGraphicsGetCurrentContext()返回的是可选CGContext,所以在Swift 3.0中使用CGContext对象的方法,必须先拆包。

C函数映射也存在于其他地方,比如读取CGPDFDocument的numberOfPages属性和CGAffineTransform。下面是新旧代码对比:

CGAffineTransformIdentity

CGAffineTransform.identity

CGAffineTransformMakeScale(2,2)

CGAffineTransform(scaleX:2, y:2)

CGAffineTransformMakeTranslation(128,128)

CGAffineTransform(translationX:128, y:128)

CGAffineTransformMakeRotation(CGFloat(M_PI))

CGAffineTransform(rotationAngle: CGFloat(M_PI))

动词和名次

先让我们看一段代码

myArray.enumerate()

myArray.enumerated()

myArray.reverse()

myArray.reversed()

每个Swift 3的修改方法都添加了d,代表这个值正被返回。还有就是在数组排序的情况下。swift 2.2 使用 sort()返回一个排序还的数组,而 sortInPlace()则实现内部排序。在Swift 3.0中 sort()变成了sorted(),sortInPlace变成了sort()。这也就意味这Swift 2.2中sort()会返回数组,而在Swift 3.0中直接内部排序。

上一篇下一篇

猜你喜欢

热点阅读