Swift3新特性
Swift3 改變了很多大量的內容,如果你的代碼中不作出必要的改變肯定會被拒絕.如果你認為Swift從1.2和2.0的改變的是很大,那是因為你還沒有看到3的改變.
本文中會盡可能通過代碼來講解Swift3的重要變化,更新代碼的時刻已經到來了.
警告# 1:有很多的變化,其中一些看起來小。然而這些變化是一個一次性的事件,使語言更好地來,同時意味著在以后版本的變化是顯著更小。
所有的函數參數標簽
Swift2.0中的原有的函數和方法調用方式發生了徹底的改變.在Swift2.x及更早版本中,方法名稱不需要設置第一個參數標簽,現在調用方式必須顯示顯示設置第一個參數的標簽,例如:
names.indexOf("Taylor")
"Taylor".writeToFile("filename", atomically: true, encoding: NSUTF8StringEncoding)
SKAction.rotateByAngle(CGFloat(M_PI_2), duration: 10)
UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
override func numberOfSectionsInTableView(tableView: UITableView) -> Int
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView?
NSTimer.scheduledTimerWithTimeInterval(0.35, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)
Swift3 要求所有的參數必須要設置標簽,除非特別設置,通過方法名中的關于第一個參數的說明已經取去除.Swift2和Swift3對比:
names.indexOf("Taylor")
names.index(of: "Taylor")
"Taylor".writeToFile("filename", atomically: true, encoding: NSUTF8StringEncoding)
"Taylor".write(toFile: "somefile", atomically: true, encoding: String.Encoding.utf8)
SKAction.rotateByAngle(CGFloat(M_PI_2), duration: 10)
SKAction.rotate(byAngle: CGFloat(M_PI_2), duration: 10)
UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
UIFont.preferredFont(forTextStyle: UIFontTextStyle.subheadline)
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)
Timer.scheduledTimer(timeInterval: 0.35, target: self, selector: #selector(createEnemy), userInfo: nil, repeats: true)
回調中,NSTimer的調用方式發生的改變,我們可以在FileManager
, Data, Date, URLRequest, UUID,NotificationCenter, 同樣的我們會發現一些基礎數據類型去除了“NS”前綴~
關于第一個標簽的設置會導致一些連鎖反應,當使用其他的框架如UIKit,他們期待原有的 "no first parameter name"規則在Swift 3.
這些是在Swift 2.2的簽名:
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
Swift3中,第一個參數標簽,通過下劃線來設置,如下:
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
省略不必要的字符
當Swift在2015年12月開放源代碼的時候,新的API標準包含三個決定性的話:“省略不必要的字。其中的變化,會使代碼調用更加簡潔.
Swift 2.2 例子:
let blue = UIColor.blueColor()
let min = numbers.minElement()
attributedString.appendAttributedString(anotherString)
names.insert("Jane", atIndex: 0)
UIDevice.currentDevice()
你能辨認出不必要的字符嗎?當使用UIColor定義藍色blue是必要的,blueColor是不必要的,Swift3中上面的代碼:
let blue = UIColor.blue
let min = numbers.min()
attributedString.append(anotherString)
names.insert("Jane", at: 0)
UIDevice.current
對比之下,代碼較之前更精簡.
Swift2.2 和 Swift3 代碼中字符串對比如下:
" Hello ".stringByTrimmingCharactersInSet(.whitespaceAndNewlineCharacterSet())
" Hello ".trimmingCharacters(in: .whitespacesAndNewlines)
"Taylor".containsString("ayl")
"Taylor".contains("ayl")
"1,2,3,4,5".componentsSeparatedByString(",")
"1,2,3,4,5".components(separatedBy: ",")
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的變化有很多,以上的對比并不是變化最大的,有些地方變化不是特別明顯:
dismiss(animated: true, completion: nil)
第一眼看到dismiss時候,是不是想到 "dismiss what?" Swift 2.2中代碼如下:
dismissViewControllerAnimated(true, completion: nil)
現在甚至是complete都是可選參數:
dismiss(animated: true)
同樣的改變發生在 prepareForSegue() 方法中,現在如下:
override func prepare(for segue: UIStoryboardSegue, sender: AnyObject?)
枚舉和屬性中的大小字母替換成小寫字母
我們在使用類和結構體,枚舉一直遵守著參數名稱以大寫字母開頭,雖然大寫字母與參數無關,Swift3中開始使用小寫字母.Swift 2.2創建 NSURLRequest對象使用 NSURLRequest(URL: someURL) ,注意大寫字母"URL". Swift 3重寫 URLRequest(url: someURL) ,同時意味著將使用 webView.request?.url?.absoluteString 來讀取webview的返回參數.
當屬性的名稱的一部分是大寫的時候就不是那么和諧,例如 cgcolor 或 cicolor ,Swift3中的調用方式如下:
let red = UIColor.red.cgColor
這種變化有利于驅動一致性,所有的屬性和參數都應該以小寫字母開頭,也沒有例外.
枚舉同樣在發生變化,從大寫改變為小寫,枚舉是一個數據類型,意味著無論你使用的任何蘋果的枚舉都將小寫:
UIInterfaceOrientationMask.Portrait // old
UIInterfaceOrientationMask.portrait // new
NSTextAlignment.Left // old
NSTextAlignment.left // new
SKBlendMode.Replace // old
SKBlendMode.replace // new
這種微小的改變涉及到了可選數據類型,原有的可選類型在枚舉中:
enum Optional { case None case Some(Wrapped)}
如果項目中原有用到了Some,需要切換到度對應的some,當然也可以通過不使用some,以下代碼供參考:
for case let .some(datum) in data {
print(datum)
}
for case let datum? in data {
print(datum)
}`
Swift形式的C函數導入
Swift3中介紹了C函數的屬性,允許開發者通過新的和簡潔的方式導入C函數.例如,從“CGContext”映射屬性的方式至一個CGContext對象.是的,這意味著原來類似CGContextSetFillColorWithColor()這種可怕的方法被移除.
為了證明這一點,以下是Swift2.2中的例子:
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()
在Swift3中CGContex可以被視作一個對象,你可以調用方式,而不是重復的使用CGContext,所有代碼重寫如下:
if let ctx = UIGraphicsGetCurrentContext() {
let rectangle = 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()
}
提示:在Swift2.2和Swift3.0中 UIGraphicsGetCurrentContext() 返回了可空的CGContext,但是因為Swift3中方式的形式調用所以使用之前需要判空.
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))
動詞和名詞
Swift3中的動詞和名詞讓人比較坤混,下面是比較重要的Swift3 API指南,讀取來有點繞:
-
"When the operation is naturally described by a verb, use the verb’s imperative for the mutating method and apply the “ed” or “ing” suffix to name its nonmutating counterpart"
-
"Prefer to name the nonmutating variant using the verb’s past participle"
- "When adding “ed” is not grammatical because the verb has a direct object, name the nonmutating variant using the verb’s present participle"
- "When the operation is naturally des
Swift3相當于給我們上了一堂英語語法課,方法的改變很微妙,有時候會讓人感到困惑.看一些簡單的代碼:
myArray.enumerate()
myArray.enumerated()
myArray.reverse()
myArray.reversed()
Swift3中在每個方法的最后都加入一個“d”,返回一個值.
當涉及到數組排序的時候這些規則有時候會導致混亂。Swift2.2中用sort()返回排序后的數組,并sortinplace()到位數組排序。Swift3,sort()更名sorted()(上述例子),和sortinplace()更名sort()。
Swift3的這些變化很容易閱讀,其中一些是微小的,但是會引入大量的破壞,蘋果讓工程師的生活更加的建安,同時也會促進工程師的技能提升.
來自:http://www.jianshu.com/p/b6abe5979e80