Swift 3.0到底有什么新東東呢?
字?jǐn)?shù)1992 閱讀2808 評論9 喜歡6
Swift 3.0 幾乎改變了一切,如果直接拿Swift 2.2的代碼在3.0的環(huán)境下構(gòu)建則一定會報錯,我們一定要做出相應(yīng)的改變。
在這篇文章中,我將盡我所能,利用代碼樣例給大家解釋Swift 3.0最重要(要命)的改變,希望大家能夠做好升級Swift 3.0 的準(zhǔn)備。Swift 3.0的改變不僅僅是我下面的這個列表,但是列表中的每一項都是對你的一個巨大的打擊。
預(yù)先警告#1:Swift 3.0 仍處于開發(fā)階段。
預(yù)先警告#2:Swift 3.0 會有很多很多的變化,其中一些可能會在細微之處。然而,我們希望這些變化是一次性的。為了使Swift可以在未來幾年更好的發(fā)展,在以后的版本更新中改變應(yīng)該的顯著變小。
預(yù)先警告#3:有些Swift 2.2的東西已經(jīng)過時了,并且被刪除了。這包括++,--,C風(fēng)格的for循環(huán),元組語法等等。
所有函數(shù)參數(shù)都有標(biāo)簽,除非你堅持
在Swift 2.0 中調(diào)用函數(shù)和方法已經(jīng)做出了改變,在3.0中又發(fā)生了變化,而這一次的改變則是徹底的、拋棄舊我的!在Swift 2.0及以前的方法名是不需要為第一個參數(shù)設(shè)置標(biāo)簽的,所以第一個參數(shù)名稱通常會內(nèi)置到方法名稱的最后,比如:
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中所有的所有的標(biāo)簽都是必須的,這也就代表著方法名不再含有參數(shù)的部分。在實際操作中,就是方法名的最后一部分被移入到了括號之中。
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)
但,還是有一些連鎖反應(yīng)的方法:當(dāng)我們連接到框架的時候,比如UIKit,這些方法希望在 Swift 3.0 中還是沿用舊有的“無第一參數(shù)名”的規(guī)則。在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中,他們都需要在第一參數(shù)前使用下劃線標(biāo)識它們使用ObjC代碼,而不使用參數(shù)標(biāo)簽。
overridefuncviewWillAppear(_animated:Bool)
overridefunctableView(_tableView:UITableView, numberOfRowsInSection section:Int) ->Int
overridefuncdidMoveToView(_view:SKView)
overridefunctraitCollectionDidChange(_previousTraitCollection:UITraitCollection?)
functextFieldShouldReturn(_textField:UITextField) ->Bool
忽略不必要的詞
當(dāng)Swift在2015年12月被開源的時候,全新的API指導(dǎo)方針包含了三個要命的詞:“忽略 不必要 詞語”,它引入了Swift 3.0 中另一個巨大的改變,因為在方法名中那些根本沒有必要出現(xiàn)的詞語將被移去。讓我們看下面的這些swift 2.2中的代碼:
letblue = UIColor.blueColor()
letmin = numbers.minElement()
attributedString.appendAttributedString(anotherString)
names.insert("Jane", atIndex:0)
UIDevice.currentDevice()
能看出代碼中的問題嗎?當(dāng)我們使用UIColor的時候,blue當(dāng)然是一個顏色,所以使用blueColor是多余的。當(dāng)我們添加一個屬性字符串到另一個的時候,這兩個東東一定都是字符串,而不可能另一個是“大象”對吧!所以,相同的代碼在Swift 3.0中就是:
letblue = UIColor.blue()
letmin = numbers.min()
attributedString.append(anotherString)
names.insert("Jane", at:0)
UIDevice.current()
正如你看到的,這個改變讓方法名稱更短了。
這種改變在字符串的操作上效果顯著,對比下面的代碼,你會發(fā)現(xiàn)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是既要添加第一參數(shù)的標(biāo)簽,又要刪除不必要的詞,所以上面的代碼實際是Swift 2.2中的
dismissViewControllerAnimated(true, completion:nil)
具有同樣效果的還有prepareForSegue方法,在Swift 3.0 中它變成了這樣:
overridefuncprepare(forsegue:UIStoryboardSegue, sender:AnyObject?)
對于枚舉和屬性,駝峰大寫前綴被替換成了駝峰小寫前綴
雖然與語法沒有什么關(guān)系,但是我們對于類、結(jié)構(gòu)、屬性和枚舉,始終遵循著一個約定:類、結(jié)構(gòu)和枚舉使用駝峰大寫前綴,屬性和參數(shù)名稱使用駝峰小寫前綴。這個約定也有例外,使用NSURLRequest(URL: someURL) 創(chuàng)建NSURLRequest對象的時候,參數(shù)就是大寫URL。Swift 3重寫了該方法為NSURLRequest(url: someURL) ,也意味著我們將會使用webView.request?.url?.absoluteString方式來讀取web view的URL。
還有一些是在屬性部分,比如說CGColor或CIColor。是的,現(xiàn)在它將會變成cgColor和ciColor。
letred = UIColor.red().cgColor
這種變化確實提高了編碼的一致性:所有的屬性和參數(shù)應(yīng)該都是以小寫開始,沒有例外!
同時,枚舉也在發(fā)生著改變,從駝峰大寫前綴改為駝峰小寫前綴。這意味著:枚舉是一個數(shù)據(jù)類型,但是枚舉值更接近屬性。然而,這意味著蘋果的枚舉現(xiàn)在都是小寫了。
UIInterfaceOrientationMask.Portrait// old
UIInterfaceOrientationMask.portrait// new
NSTextAlignment.Left// old
NSTextAlignment.left// new
SKBlendMode.Replace// old
SKBlendMode.replace// new
Swift 引入 C 函數(shù)
Swift 3引入C函數(shù)的屬性。比如,所有以CGContext開頭的函數(shù)現(xiàn)在都被映射為CGContext對象上的屬性方法,這樣我們就可以不再使用令我們非常痛苦的CGContextSetFillColorWithColor()函數(shù)了。
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被作為對象處理,我們可以直接調(diào)用方法了。
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函數(shù)映射也存在于其他地方,比如讀取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,代表這個值正被返回。還有就是在數(shù)組排序的情況下。swift 2.2 使用 sort()返回一個排序還的數(shù)組,而 sortInPlace()則實現(xiàn)內(nèi)部排序。在Swift 3.0中 sort()變成了sorted(),sortInPlace變成了sort()。這也就意味這Swift 2.2中sort()會返回數(shù)組,而在Swift 3.0中直接內(nèi)部排序。