`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 會有很多很多的變化欧漱,其中一些可能會在細(xì)微之處职抡。然而,我們希望這些變化是一次性的误甚。為了使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)
override func numberOfSectionsInTableView(tableView:UITableView) ->Int
override func numberOfSections(in tableView:UITableView) ->Int
func viewForZoomingInScrollView(scrollView:UIScrollView) ->UIView?
func viewForZooming(in scrollView: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 中:
override func viewWillAppear(animated:Bool)
override func tableView(tableView:UITableView, numberOfRowsInSection section:Int) ->IntoverridefuncdidMoveToView(view:SKView)
override func traitCollectionDidChange(previousTraitCollection:UITraitCollection?)
func textFieldShouldReturn(textField:UITextField) ->Bool
在 Swift 3.0中随珠,他們都需要在第一參數(shù)前使用下劃線標(biāo)識它們使用ObjC代碼灭袁,而不使用參數(shù)標(biāo)簽。
override func viewWillAppear(_animated:Bool)
override func tableView(_tableView:UITableView, numberOfRowsInSection section:Int) ->Int
override func didMoveToView(_view:SKView)
override func traitCollectionDidChange(_previousTraitCollection:UITraitCollection?)
func textFieldShouldReturn(_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中的代碼:
let ctx = UIGraphicsGetCurrentContext()
let rectangle = 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)用方法了同诫。
if let ctx = 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)部排序串塑。