// 從第一個參數就必須指定參數名,除非使用"_"明確指出省略參數 func sum(num1:Int,num2:Int)->Int{ return num1 + num2 } sum(num1: 1, num2: 2) // old: sum(1,2)或者sum(1, num2: 2)
//func increase(var a:Int){ // a += 1 //} // 上面的代碼會報錯,可改寫成 func increase(a:Int){ var a = a a += 1 }
//func increase(inout a:Int) { // a += 1 //} // 上面的代碼會報錯,可改成 func increase( a:inout Int) { a += 1 }
@discardableResult聲明,告訴編譯器此方法能夠不用接收返回值。
struct Caculator { func sum(a:Int,b:Int) -> Int { return a + b } @discardableResult func func1(a:Int,b:Int) ->Int { return a - b + 1 } } let ca = Caculator() ca.sum(a: 1, b: 2) // 此處會警告,由於方法有返回值可是沒有接收 let _ = ca.sum(a: 1, b: 2) // 使用"_"接收無用返回值 ca.func1(a: 1, b: 2) // 因爲func1添加了@discardableResult聲明,即便不接收返回值也不會警告
可選類型
Swift3.0對於可選類型控制更加嚴謹,隱式可選類型和其餘類型的運算以後得到的是可選類型而不是隱式可選類型。
let a:Int! = 1 let b = a + 1 // 此時強制解包,b是Int型 let c = a // 注意此時c是Int? 在以前的Swift版本中c是Int!
Selector的變化
Selector的改變其實從1.0到3.0經歷了屢次變化,從最先的@Selector("method:")到如今的#selector(method(param1:))能夠說經歷了屢次修改,好在它變得愈來愈好,畢竟字符串操做對於語法檢查來講是很無助的。
class MyClass { @objc func sum(a:Int,b:Int) -> Int { return a + b } func func1(){ let _ = #selector(sum(a:b:)) } } // old: Swift 2.2 //class MyClass { // @objc func sum(a:Int,b:Int) -> Int { // return a + b // } // // func func1(){ // let _ = #selector(sum(_:b:)) // } //}
class MyClass { @objc func sum(a:Int,b:Int) -> Int { return a + b } func func1(){ let _ = #selector(sum(a:b:)) } } // old: Swift 2.2 //class MyClass { // @objc func sum(a:Int,b:Int) -> Int { // return a + b // } // // func func1(){ // let _ = #selector(sum(_:b:)) // } //}
class MyClass { @objc func sum(a:Int,b:Int) -> Int { return a + b } func func1(){ let _ = #selector(sum(a:b:)) } } // old: Swift 2.2 //class MyClass { // @objc func sum(a:Int,b:Int) -> Int { // return a + b // } // // func func1(){ // let _ = #selector(sum(_:b:)) // } //}
協議中的可選方法
在Swift3.0以前若是要定義協議中可選方法,只須要給協議加上@objc以後方法使用optional修飾就能夠了,可是Swift3.0中除了協議須要@objc修飾,可選方法也必須使用@objc來修飾。
@objc protocol MyProtocol { @objc optional func func1() //old: optional func func1() func func2() }
@objc protocol MyProtocol { @objc optional func func1() //old: optional func func1() func func2() }
@objc protocol MyProtocol { @objc optional func func1() //old: optional func func1() func func2() }
取消++、--操做符
var d = 1 d++ //報錯,能夠改寫成 d += 1 或者 d = d + 1
var d = 1 d++ //報錯,能夠改寫成 d += 1 或者 d = d + 1
var d = 1 d++ //報錯,能夠改寫成 d += 1 或者 d = d + 1
取消C風格for循環
//for var i = 0 ;i < 10 ; i += 1 { // debugPrint(i) //} // 上面的代碼會報錯,可改寫成以下代碼 for i in 0 ..< 10 { debugPrint(i) }
//for var i = 0 ;i < 10 ; i += 1 { // debugPrint(i) //} // 上面的代碼會報錯,可改寫成以下代碼 for i in 0 ..< 10 { debugPrint(i) }
//for var i = 0 ;i < 10 ; i += 1 { // debugPrint(i) //} // 上面的代碼會報錯,可改寫成以下代碼 for i in 0 ..< 10 { debugPrint(i) }
2、SDK類庫變化
你們都知道Swift誕生在Objective-C已經發展的至關成熟的狀況下,爲了保證ObjC開發人員順利過渡到Swift,也由於Swift處於初級階段,不少類庫和方法命名都儘可能和ObjC保持一致,在使用Swift開發iOS應用中到處能夠看到ObjC的影子。可是做爲一門Modern語言Swift仍是作出了改變,從中能夠看出往後Swift將完全擺脫ObjC的影子。這其中包括從新導入Foundation消除類型前綴、方法名去重、函數和方法去C風格等等。
命名
// 1.去掉前綴 let url1 = URL(string: "www.cmjstudio.com") let isFileURL = url1?.isFileURL //old:url1.fileURL ,如今更加註重語意 let data1 = Data() //NSData // 2.方法名使用動詞,其餘名詞、介詞等做爲參數或移除 var array1 = [1,2,3] array1.append(contentsOf: [4,5,6]) // old:array1.appendContentsOf([4,5,6]) array1.remove(at: 0) // old:array1.removeAtIndex(0) // 3.不引發歧義的狀況下儘可能消除重複 let color1 = UIColor.red() // old:var color1 = UIColor.redColor() // 4.枚舉成員首字母變成小寫 let label1 = UILabel() label1.textAlignment = .center // old:label1.textAlignment = .Center // 5.按鈕的Normal狀態去掉 let btn1 = UIButton() btn1.setTitle("hello", for: UIControlState()) // 至關於Normal狀態
// 1.去掉前綴 let url1 = URL(string: "www.cmjstudio.com") let isFileURL = url1?.isFileURL //old:url1.fileURL ,如今更加註重語意 let data1 = Data() //NSData // 2.方法名使用動詞,其餘名詞、介詞等做爲參數或移除 var array1 = [1,2,3] array1.append(contentsOf: [4,5,6]) // old:array1.appendContentsOf([4,5,6]) array1.remove(at: 0) // old:array1.removeAtIndex(0) // 3.不引發歧義的狀況下儘可能消除重複 let color1 = UIColor.red() // old:var color1 = UIColor.redColor() // 4.枚舉成員首字母變成小寫 let label1 = UILabel() label1.textAlignment = .center // old:label1.textAlignment = .Center // 5.按鈕的Normal狀態去掉 let btn1 = UIButton() btn1.setTitle("hello", for: UIControlState()) // 至關於Normal狀態
// 1.去掉前綴 let url1 = URL(string: "www.cmjstudio.com") let isFileURL = url1?.isFileURL //old:url1.fileURL ,如今更加註重語意 let data1 = Data() //NSData // 2.方法名使用動詞,其餘名詞、介詞等做爲參數或移除 var array1 = [1,2,3] array1.append(contentsOf: [4,5,6]) // old:array1.appendContentsOf([4,5,6]) array1.remove(at: 0) // old:array1.removeAtIndex(0) // 3.不引發歧義的狀況下儘可能消除重複 let color1 = UIColor.red() // old:var color1 = UIColor.redColor() // 4.枚舉成員首字母變成小寫 let label1 = UILabel() label1.textAlignment = .center // old:label1.textAlignment = .Center // 5.按鈕的Normal狀態去掉 let btn1 = UIButton() btn1.setTitle("hello", for: UIControlState()) // 至關於Normal狀態
去C風格
Swift發展初期不少類庫的引入依然保持的ObjC風格,可是ObjC因爲根出C語言,所以不少操做其實並非對象和方法操做而是C語言的函數形式。到了Swift3.0以後這一現狀將發生變化,全局函數將會變成某些類型的方法;某些常量定義將以某個枚舉類型的成員來表示。
let rect1 = CGRect(x: 0, y: 0, width: 100, height: 100) // 下面的代碼將要報錯,3.0徹底廢除這種類C的風格 //let rect1 = CGRectMake(0, 0, 100, 100) if let context1 = UIGraphicsGetCurrentContext() { CGContext.fillPath(context1) // old:CGContextFillPath(context1!) } // GCD的改變 let queue = DispatchQueue(label: "myqueue") queue.async { debugPrint("hello world!") } // old: //let queue = dispatch_queue_create("myqueue", nil) //dispatch_async(queue) { // debugPrint("hello world!") //} // 相關常量定義被移到枚舉內部 NotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: UserDefaults.didChangeNotification, object: nil) //old:NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: NSUserDefaultsDidChangeNotification, object: nil)
let rect1 = CGRect(x: 0, y: 0, width: 100, height: 100) // 下面的代碼將要報錯,3.0徹底廢除這種類C的風格 //let rect1 = CGRectMake(0, 0, 100, 100) if let context1 = UIGraphicsGetCurrentContext() { CGContext.fillPath(context1) // old:CGContextFillPath(context1!) } // GCD的改變 let queue = DispatchQueue(label: "myqueue") queue.async { debugPrint("hello world!") } // old: //let queue = dispatch_queue_create("myqueue", nil) //dispatch_async(queue) { // debugPrint("hello world!") //} // 相關常量定義被移到枚舉內部 NotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: UserDefaults.didChangeNotification, object: nil) //old:NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: NSUserDefaultsDidChangeNotification, object: nil)
let rect1 = CGRect(x: 0, y: 0, width: 100, height: 100) // 下面的代碼將要報錯,3.0徹底廢除這種類C的風格 //let rect1 = CGRectMake(0, 0, 100, 100) if let context1 = UIGraphicsGetCurrentContext() { CGContext.fillPath(context1) // old:CGContextFillPath(context1!) } // GCD的改變 let queue = DispatchQueue(label: "myqueue") queue.async { debugPrint("hello world!") } // old: //let queue = dispatch_queue_create("myqueue", nil) //dispatch_async(queue) { // debugPrint("hello world!") //} // 相關常量定義被移到枚舉內部 NotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: UserDefaults.didChangeNotification, object: nil) //old:NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(userDefaultChange()), name: NSUserDefaultsDidChangeNotification, object: nil)
集合API的變化
let array1 = [1,2,3] let next = array1.index(after: 0) // old:let start = array1.startIndex let next = start.successor() let first = array1.first { (element) -> Bool in // 增長新的方法 element > 1 } let r = Range(0..<3) //old: let _ = NSRange(location: 0, length: 3) // 下面的代碼必須在控制器中執行,用於遍歷當前view及其父視圖 for subview in sequence(first: self.view, next: { $0?.superview }){ debugPrint(subview) }
let array1 = [1,2,3] let next = array1.index(after: 0) // old:let start = array1.startIndex let next = start.successor() let first = array1.first { (element) -> Bool in // 增長新的方法 element > 1 } let r = Range(0..<3) //old: let _ = NSRange(location: 0, length: 3) // 下面的代碼必須在控制器中執行,用於遍歷當前view及其父視圖 for subview in sequence(first: self.view, next: { $0?.superview }){ debugPrint(subview) }
let array1 = [1,2,3] let next = array1.index(after: 0) // old:let start = array1.startIndex let next = start.successor() let first = array1.first { (element) -> Bool in // 增長新的方法 element > 1 } let r = Range(0..<3) //old: let _ = NSRange(location: 0, length: 3) // 下面的代碼必須在控制器中執行,用於遍歷當前view及其父視圖 for subview in sequence(first: self.view, next: { $0?.superview }){ debugPrint(subview) }
新的浮點協議
Float、Double、CGFloat使用了新的協議,提供了提供 IEEE-754標準的屬性和方法。
let a = 2 * Float.pi // old: let a = 2 * M_PI let b = 2.0 * .pi // 注意前面是浮點型,後面能夠省略Float
let a = 2 * Float.pi // old: let a = 2 * M_PI let b = 2.0 * .pi // 注意前面是浮點型,後面能夠省略Float
let a = 2 * Float.pi // old: let a = 2 * M_PI let b = 2.0 * .pi // 注意前面是浮點型,後面能夠省略Float
3、從Swift_2.2遷移到Swift_3.0
能夠看出若是要更新到Swift3.0現有項目須要做出大量修改,通過使用以前的項目進行測試,區區十個類文件就出現了一百多個錯誤,不過好在Xcode 8已經提供了很好用的遷移工具(Xcode:Editor - Convert - To Current Swift Syntax),通過遷移工具轉化後僅僅發現兩處錯誤須要手動修正。在使用這個工具的時候你們會看到以下界面:
Swift 2.3?沒錯Swift2.2和Swift 3.0中間還有個Swift 2.3,Apple也解釋了什麼是Swift 2.3,其實就是Swift 2.2 + New SDKs。之因此如此是由於Xcode 8目前仍是beta版,使用Swift 3.0進行開發的應用還不能提交App Store,所以在Swift 2.2基礎上使用新的SDK開發仍是有存在必要的。
Swift 2.3?沒錯Swift2.2和Swift 3.0中間還有個Swift 2.3,Apple也解釋了什麼是Swift 2.3,其實就是Swift 2.2 + New SDKs。之因此如此是由於Xcode 8目前仍是beta版,使用Swift 3.0進行開發的應用還不能提交App Store,所以在Swift 2.2基礎上使用新的SDK開發仍是有存在必要的。