Swift 3.0 幾乎改變了一切,如果直接拿Swift 2.2的代碼在3.0的環(huán)境下構(gòu)建則一定會(huì)報(bào)錯(cuò)饭宾,我們一定要做出相應(yīng)的改變批糟。
在這篇文章中,我將盡我所能看铆,利用代碼樣例給大家解釋Swift 3.0最重要(要命)的改變徽鼎,希望大家能夠做好升級(jí)Swift 3.0 的準(zhǔn)備。Swift 3.0的改變不僅僅是我下面的這個(gè)列表弹惦,但是列表中的每一項(xiàng)都是對(duì)你的一個(gè)巨大的打擊纬傲。
預(yù)先警告#1:Swift 3.0 仍處于開發(fā)階段。
預(yù)先警告#2:Swift 3.0 會(huì)有很多很多的變化肤频,其中一些可能會(huì)在細(xì)微之處叹括。然而,我們希望這些變化是一次性的宵荒。為了使Swift可以在未來幾年更好的發(fā)展汁雷,在以后的版本更新中改變應(yīng)該的顯著變小。
預(yù)先警告#3:有些Swift 2.2的東西已經(jīng)過時(shí)了报咳,并且被刪除了侠讯。這包括++,--暑刃,C風(fēng)格的for循環(huán)厢漩,元組語法等等。
所有函數(shù)參數(shù)都有標(biāo)簽岩臣,除非你堅(jiān)持
在Swift 2.0 中調(diào)用函數(shù)和方法已經(jīng)做出了改變溜嗜,在3.0中又發(fā)生了變化,而這一次的改變則是徹底的架谎、拋棄舊我的炸宵!在Swift 2.0及以前的方法名是不需要為第一個(gè)參數(shù)設(shè)置標(biāo)簽的,所以第一個(gè)參數(shù)名稱通常會(huì)內(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ù)的部分。在實(shí)際操作中会涎,就是方法名的最后一部分被移入到了括號(hào)之中裹匙。
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)我們連接到框架的時(shí)候末秃,比如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)識(shí)它們使用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月被開源的時(shí)候贺待,全新的API指導(dǎo)方針包含了三個(gè)要命的詞:“忽略 不必要 詞語”徽曲,它引入了Swift 3.0 中另一個(gè)巨大的改變,因?yàn)樵诜椒心切└緵]有必要出現(xiàn)的詞語將被移去麸塞。讓我們看下面的這些swift 2.2中的代碼:
letblue = UIColor.blueColor()
letmin = numbers.minElement()
attributedString.appendAttributedString(anotherString)
names.insert("Jane", atIndex:0)
UIDevice.currentDevice()
能看出代碼中的問題嗎秃臣?當(dāng)我們使用UIColor的時(shí)候,blue當(dāng)然是一個(gè)顏色哪工,所以使用blueColor是多余的奥此。當(dāng)我們添加一個(gè)屬性字符串到另一個(gè)的時(shí)候,這兩個(gè)東東一定都是字符串雁比,而不可能另一個(gè)是“大象”對(duì)吧稚虎!所以,相同的代碼在Swift 3.0中就是:
letblue = UIColor.blue()
letmin = numbers.min()
attributedString.append(anotherString)
names.insert("Jane", at:0)
UIDevice.current()
正如你看到的偎捎,這個(gè)改變讓方法名稱更短了蠢终。
這種改變?cè)谧址牟僮魃闲Ч@著,對(duì)比下面的代碼茴她,你會(huì)發(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 仍然是一個(gè)屬性丈牢,但是lowercaseString 和 uppercaseString 改頭換面成為方法 lowercased() 和 uppercased()了祭钉。
還有一個(gè)Swift 3.0的方法是下面這樣:
dismiss(animated:true, completion:nil)
你可能會(huì)想,我們要dismiss什么呢己沛?Swift 3.0是既要添加第一參數(shù)的標(biāo)簽慌核,又要?jiǎng)h除不必要的詞,所以上面的代碼實(shí)際是Swift 2.2中的
dismissViewControllerAnimated(true, completion:nil)
具有同樣效果的還有prepareForSegue方法申尼,在Swift 3.0 中它變成了這樣:
overridefuncprepare(forsegue:UIStoryboardSegue, sender:AnyObject?)
對(duì)于枚舉和屬性遂铡,駝峰大寫前綴被替換成了駝峰小寫前綴
雖然與語法沒有什么關(guān)系,但是我們對(duì)于類晶姊、結(jié)構(gòu)扒接、屬性和枚舉会放,始終遵循著一個(gè)約定:類附迷、結(jié)構(gòu)和枚舉使用駝峰大寫前綴,屬性和參數(shù)名稱使用駝峰小寫前綴境输。這個(gè)約定也有例外蒙挑,使用NSURLRequest(URL: someURL) 創(chuàng)建NSURLRequest對(duì)象的時(shí)候宗侦,參數(shù)就是大寫URL。Swift 3重寫了該方法為NSURLRequest(url: someURL) 忆蚀,也意味著我們將會(huì)使用webView.request?.url?.absoluteString方式來讀取web view的URL矾利。
還有一些是在屬性部分姑裂,比如說CGColor或CIColor。是的男旗,現(xiàn)在它將會(huì)變成cgColor和ciColor舶斧。
letred = UIColor.red().cgColor
這種變化確實(shí)提高了編碼的一致性:所有的屬性和參數(shù)應(yīng)該都是以小寫開始,沒有例外察皇!
同時(shí)茴厉,枚舉也在發(fā)生著改變,從駝峰大寫前綴改為駝峰小寫前綴什荣。這意味著:枚舉是一個(gè)數(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對(duì)象上的屬性方法泞辐,這樣我們就可以不再使用令我們非常痛苦的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被作為對(duì)象處理竞滓,我們可以直接調(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對(duì)象的方法商佑,必須先拆包锯茄。
C函數(shù)映射也存在于其他地方,比如讀取CGPDFDocument的numberOfPages屬性和CGAffineTransform茶没。下面是新舊代碼對(duì)比:
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))
動(dòng)詞和名次
先讓我們看一段代碼
myArray.enumerate()
myArray.enumerated()
myArray.reverse()
myArray.reversed()
每個(gè)Swift 3的修改方法都添加了d肌幽,代表這個(gè)值正被返回。還有就是在數(shù)組排序的情況下抓半。swift 2.2 使用 sort()返回一個(gè)排序還的數(shù)組喂急,而 sortInPlace()則實(shí)現(xiàn)內(nèi)部排序。在Swift 3.0中 sort()變成了sorted()笛求,sortInPlace變成了sort()廊移。這也就意味這Swift 2.2中sort()會(huì)返回?cái)?shù)組,而在Swift 3.0中直接內(nèi)部排序探入。