前段時間搞了一段時間的swift(swift3.0以前的版本),各種基礎控件和知識點的樣例demo已完成,還沒有來得及喘口氣,swift3.0來了,于是就直接用最新的版本來跑了一下工程,build一下立馬嚇暈了,好幾十個錯誤,這是什么鬼?swift3.0改變這么多嗎?雖然可以設置兼容版本,但是swift3.0是最新版,也是以后必須要使用的最低版本(說不定還有swift4.0,swift5.0,誰知道呢),所以我放棄了兼容性的設置,還是直接用swift3.0,于是一個類文件一個類文件的去改,修改中發現雖然語法什么的改變了很多,但是客觀來說,這個改變確實是越來越好,越來越規范,越來越簡潔。下面就swift3.0的新特性來簡單說一下。
一、基礎語法知識改動
1. ?去除了oc中常用的++、-- 運算符操作,當然還是可以通過+=、-= 來實現相應的功能。
2. ?之前使用的for循環格式 for var i = 0;i<100;i++{ //code here? }已被遺棄,取而代之的是 for i in 1...100{//code here }、(1...10).forEach {//code here}
3. 所有的函數參數都有帶上形參標簽,3.0之前的版本一般是從第二個參數開始才帶參數標簽,3.0以后第一個也要加上形參標簽,這個感覺有點增加工作量,其實從安全角度考慮還是值得的。
let sum = add(a: 2, b: 10)
func add(a:Int, b:Int) -> Int{
return a + b
}
4. 移除了 NS 前綴,替換為下面的展示形式
let file = Bundle.main.path(forResource: "demo", ofType: "json")
let url = URL(fileURLWithPath: file!)
let data = try! Data(contentsOf: url)
let json = try! JSONSerialization.jsonObject(with: data)
print(json)
5.數組排序函數的改變,過去數組排序的兩個方法:sortInPlace() 和 sort(),現在分別改名成 sort() 和 sorted()
sort() 是直接對目標數組進行排序。sorted() 是返回一個排序后的數組,原數組不變。
var array1 = [1, 5, 3, 2, 4]
array1.sort()
print(array1)? //[1, 2, 3, 4, 5]
var array2 = [1, 5, 3, 2, 4]
let sortedArray = array2.sorted()
print(array2)? //[1, 5, 3, 2, 4]
print(sortedArray)? //[1, 2, 3, 4, 5]
6. 數組的反轉和遍歷的改變,過去 reverse() 方法實現數組反轉,enumerate() 方法實現遍歷。現這兩個方法都加上 ed 后綴(reversed、enumerated)
for i in (1...100).reversed() {
print(i)
}
let array = [1, 5, 3, 2, 4]
for (index, value) in array.enumerated() {
print("\(index + 1) \(value)")
}
7. 枚舉成員變成小寫字母開頭
Swift 3.0 將枚舉成員當做屬性來看,所以現在使用小寫字母開頭而不是以前的大寫字母,這種寫法更符合駝峰式的編寫規范。
.system //過去是:.System
.touchUpInside //過去是:.TouchUpInside
.fillStroke //過去是:.FillStroke
.cgColor //過去是:.CGColor
二、UI層面的改動(簡要的舉例一下,更多的自己在工程中體驗,都有提示輸出的)
swift3.0在UI的層面改動了不少,不過相對之前的版本來說,這個改動更加簡潔,更加符合使用習慣。
1. 移除了多余的API詞語,而且將之前的大寫開頭的(比如.Normal)改了了小寫形式(.normal)更加符合我們以往oc的規范和習慣。
UIApplication .sharedApplicaton 改為UIApplication .shared
NSTextAlignmentCenter改為NSTextAlignment.center
UIColor.blueColor() 改為 UIColor.blue
button.setTitle(forState) 改為 button.setTitle(for)
button.addTarget(action, forControlEvents) 改為 button.addTarget(action, for)
arr.minElement() 改為 arr.min()
arr.maxElement() 改為 arr.max()
attributedString.appendAttributedString(anotherString) 改為 attributedString.append(anotherString)
names.insert("Jane", atIndex: 0) 改為 names.insert("Jane", at: 0)
NSBundle.mainBundle() 改為 Bundle.main
UIDevice.currentDevice() 改為 UIDevice.current
NSData(contentsOfURL) 改為 Data(contentsOf)
NSJSONSerialization.JSONObjectWithData() 改為 JSONSerialization.jsonObject(with)
2. 取消了CGRectMake(0,0,100,100)方法,用CGRect(x:0 ,y:0,width:100,height:100)替換,取消了CGPointMake(0, 0),用CGPoint(x: 0, y: 0)替換,取消了CGSizeMake(20, 20),用CGSize(width: 20, height: 20)替換
3.特別要提醒的是函數的方法名(無參和有參)
之前對按鈕添加事件的時候可以直接用字符串來作為函數的方法名,例如,backBtn.addTarget(self, action: “backAction”, forUIControlEvents: .touchUpInside),3.0以后就取消了這種定義方式,而是改成了#selector的方式,backBtn.addTarget(self, action: #selector(backAction), for: UIControlEvents.touchUpInside),上面說的是對于沒有參數的方法而言,對于帶有參數的方法,這里就要注意了,之前對按鈕添加有參的事件方法可以是backBtn.addTarget(self, action: “backAction:”, forUIControlEvents: .touchUpInside)或backBtn.addTarget(self, action: #selector(backAction:), forUIControlEvents: .touchUpInside),3.0以后這兩個方式都被取消了,而是用backBtn.addTarget(self, action: #selector(backAction(_:)), for: UIControlEvents.touchUpInside)
如果是對于手勢操作,函數中的參數定義要和實現中的保持一致
//長按監聽
let longPress=UILongPressGestureRecognizer(target:self,
action:#selector(longPressDid(sender:)))
self.view.addGestureRecognizer(longPress)
//長按手勢,
func longPressDid(sender: UILongPressGestureRecognizer){
if sender.state == .began {
print("長按響應開始")
} else {
print("長按響應結束")
}
}
開關控件和日期控件的選擇事件的命名同上。
三、GCD方面的改變
GCD方面的語法形式改動的也不小,之前的版本和OC的風格還是比較相近的,但是swift3.0中變化很大,dispatch 的全局函數不再寫為下劃線風格的名稱了,它變成了一個更符合 Swift 風格的 DispatchQueue 。
1.主線程
過去是通過 dispatch_get_main_queue ( ) 來獲取主線程,現在是用 DispatchQueue .main,只需要在線程后邊使用.async{ } 即可,
DispatchQueue.main.async {
//code here?
}
2.優先級 名稱
過去GCD 的默認隊列優先級有四個:
? DISPATCH_QUEUE_PRIORITY_HIGH
? DISPATCH_QUEUE_PRIORITY_DEFAULT
? DISPATCH_QUEUE_PRIORITY_LOW
? DISPATCH_QUEUE_PRIORITY_BACKGROUND
swift3.0 中,這四個優先級的名字更加簡潔易懂:
? .userInitialted (對應之前的DISPATCH_QUEUE_PRIORITY_HIGH)
? .default(對應之前的DISPATCH_QUEUE_PRIORITY_DEFAULT)
? .utility(對應之前的DISPATCH_QUEUE_PRIORITY_LOW)
? .background(對應之前的DISPATCH_QUEUE_PRIORITY_BACKGROUND)
3. 獲取一個隊列
swift3.0使用 DispatchQueue.global ( ) 獲取一個系統的隊列(系統自帶的全局并發隊列),這樣的話獲取的就是默認 .default優先級的隊列了,如果要獲取其他優先級的隊列,就使用DispatchQueue.global(qos:.userInitiated),最后,我們使用 . async{} 來執行代碼:
DispatchQueue.global(qos: .userInitiated).async {
? ?//code here
}
4. 創建一個隊列
直接用 DispatchQueue 的初始化器來創建一個隊列。最簡單直接的辦法是這樣:
let queue = DispatchQueue(label: "myBackgroundQueue"){?
//code here?
}
你可以指定優先級以及隊列類別:
let queue = DispatchQueue(label: "myBackgroundQueue", qos: .userInitiated, attributes: .concurrent)
{
//code here
}
5. 隊列組?
對于組,可以使用這樣的語法直接創建一個組:
let group = DispatchGroup()
至于使用,則是這樣的:
let group = DispatchGroup()
let queue = DispatchQueue(label: "myBackgroundQueue")
queue.async(group:group) {
print("background working")
}
那么,如果有多個并發隊列在同一個組里,我們需要它們完成了再繼續呢?
group.wait()
6. 指定時間后執行操作
這個大家知道在swift3.0之前實現這個功能還是比較繁瑣的,特別是哪些系統宏的使用,但是swift3.0以后,這個實現就變的非常簡單了,只需如下代碼即可。
//下面的x就是你想延遲執行的秒數
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + x) {
?//code here?
}
swift3.0的變動還有很多細節方面的,這里就不一一陳述了,具體的變化還是要在實際使用時才能更好的體會到。