swift學習:
一、線程(Thread)接口簡單用法
首先筆者一直在做安卓開發,只是一位ios的初學者,以下內容如有不正確之處,還望各位大牛們指出。
在網上很多帖子裡面,我有看到大家常使用的NSThread,可能因為我的XCode已經更新到了8.0,demo 默認的SDK版本為10.0,不幸的NSThread已經被Thread替代。
開發說明中可以看到,Thread提供了三個初始化方法:
第二個初始化方參數說明:
target: selector消息發送到得對象
selector:這個對象向target發送消息。selector必須攜帶一個參數並且沒有返回值。
argument:發個target的參數,可能是nil
(總感覺google的開發說明易懂)也許結合Object-C的廣播調用機制來理解,selector是線程處理事務的方法,在Object-c中調用一個方法,會以廣播形式把函數名,和參數傳給對應對象。
var thread1: Thread?
thread1 = Thread(target: self, selector: “thread1ToDo”, object: nil)
我用老方式傳入參數,運行報錯了
我先按提示修改
再修改
終於通過了,
下面來看第三個初始化函數:
汗,沒有說明!!但是看以上的定義格式可以知道,block是閉包。
由XCode給出的一些版本判斷看得出,該接口是iOS10.0加入的。若相兼容其他版本的的系統,使用該方式,顯得有些繁瑣。
關於第一個初始化方式,筆者沒有在開發說明中找到set selector的函數,暫時不明白怎麼把事務添加到線程實例中去運行。
除了直接創建線程實例,iOS還提供了使用線程的其他方式,API描述中:
這裡注意到detachNewThread開頭的兩個方法,從字面意思來理解這兩個方法應該是直接啟動一個新的線程處理對應的事務。這個兩個函數的而參數與之前的初始化函數相似,可以參考以上說明。
使用實例:
線程控制:
開發說明文檔Thread的概述是這樣說的:
大概的意思就是,Thread支持運行狀態判斷,你可以根據自己的需要在適當時候取消正在運行的線程結束它的任務。以下是狀態讀取接口:
上面的函數根據命名就知道每個函數的功能了,就不多解釋了,下面再來看線程控制函數:
前三個為類函數,根據調用的位置決定,作用所在當前線程。
下面貼一些測試代碼,實驗一下接口
import UIKit
class ViewController: UIViewController {
var thread1: Thread?
var thread2: Thread?
override func viewDidLoad() {
super.viewDidLoad()
thread1 = Thread(target: self, selector: #selector(ViewController.thread1ToDo), object: nil)
thread2 = Thread(target: self, selector: #selector(ViewController.thread2ToDo), object: nil)
thread1?.start()
thread2?.start()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@objc func thread1ToDo() {
for i in 1...30 {
if i % 3 == 0 {
Thread.sleep(forTimeInterval: 1)
}
print("I'm thread1 -- \(i)")
}
}
@objc func thread2ToDo(sender: AnyObject?) {
for i in 1...30 {
if i % 3 == 0 {
Thread.sleep(forTimeInterval: 1)
}
print("I'm thread2 -- \(i)")
}
}
}
此時運行結果:兩條線程輸出在時序上市隨機的,下面做些調整使得兩條線程有序的輸出。
現在我們引入NSCondition這個類。還是先看看類的介紹說明
這個說明大概的意思是,這個類描述了一個條件變量,這個變量在線程中同時起著Lock和條件檢查點的作用,lock功能保護代碼運行邏輯並在條件滿足時執行任務,而檢查點,在線程運行時只有檢查點判定為真時才繼續執行任務,否則線程阻塞在此,直到在其他線程被喚醒。相關流程開發文當中也有說明
以下調整以下上面的代碼:
import UIKit
class ViewController: UIViewController {
var con1 = NSCondition()
var con2 = NSCondition()
var thread1: Thread?
var thread2: Thread?
override func viewDidLoad() {
super.viewDidLoad()
thread1 = Thread(target: self, selector: #selector(ViewController.thread1ToDo), object: nil)
thread2 = Thread(target: self, selector: #selector(ViewController.thread2ToDo), object: nil)
thread1?.start()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
@objc func thread1ToDo() {
for i in 1...30 {
if i % 3 == 0 {
if thread2!.isExecuting {
con2.signal()
} else {
thread2?.start()
}
con1.lock()
con1.wait()
con1.unlock()
}
print("I'm thread1 -- \(i)")
}
print("I'm thread1 over!!")
}
@objc func thread2ToDo(sender: AnyObject?) {
for i in 1...30 {
if i % 3 == 0 {
con1.signal()
con2.lock()
con2.wait()
con2.unlock()
}
print("I'm thread2 -- \(i)")
}
print("I'm thread2 over!!")
}
}