スウィフトでスレッドを使用するには?
dispatchOnMainThread:^{
NSLog(@"Block Executed On %s", dispatch_queue_get_label(dispatch_get_current_queue()));
}];
スウィフトでスレッドを使用するには?
dispatchOnMainThread:^{
NSLog(@"Block Executed On %s", dispatch_queue_get_label(dispatch_get_current_queue()));
}];
swift5 での Dan Beaulieu の回答 (Swift 3.0.1 以降も機能)。
extension DispatchQueue {
static func background(delay: Double = 0.0, background: (()->Void)? = nil, completion: (() -> Void)? = nil) {
DispatchQueue.global(qos: .background).async {
background?()
if let completion = completion {
DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {
completion()
})
}
}
}
}
DispatchQueue.background(delay: 3.0, background: {
// do something in background
}, completion: {
// when background job finishes, wait 3 seconds and do something in main thread
})
DispatchQueue.background(background: {
// do something in background
}, completion:{
// when background job finished, do something in main thread
})
DispatchQueue.background(delay: 3.0, completion:{
// do something in main thread after 3 seconds
})
In Swift 4.2 and Xcode 10.1
We have three types of Queues :
1. Main Queue: Main queue is a serial queue which is created by the system and associated with the application main thread.
2. Global Queue : Global queue is a concurrent queue which we can request with respect to the priority of the tasks.
3. Custom queues : can be created by the user. Custom concurrent queues always mapped into one of the global queues by specifying a Quality of Service property (QoS).
DispatchQueue.main//Main thread
DispatchQueue.global(qos: .userInitiated)// High Priority
DispatchQueue.global(qos: .userInteractive)//High Priority (Little Higher than userInitiated)
DispatchQueue.global(qos: .background)//Lowest Priority
DispatchQueue.global(qos: .default)//Normal Priority (after High but before Low)
DispatchQueue.global(qos: .utility)//Low Priority
DispatchQueue.global(qos: .unspecified)//Absence of Quality
These all Queues can be executed in two ways
1. Synchronous execution
2. Asynchronous execution
DispatchQueue.global(qos: .background).async {
// do your job here
DispatchQueue.main.async {
// update ui here
}
}
//Perform some task and update UI immediately.
DispatchQueue.global(qos: .userInitiated).async {
// Perform task
DispatchQueue.main.async {
// Update UI
self.tableView.reloadData()
}
}
//To call or execute function after some time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
//Here call your function
}
//If you want to do changes in UI use this
DispatchQueue.main.async(execute: {
//Update UI
self.tableView.reloadData()
})
From AppCoda : https://www.appcoda.com/grand-central-dispatch/
//This will print synchronously means, it will print 1-9 & 100-109
func simpleQueues() {
let queue = DispatchQueue(label: "com.appcoda.myqueue")
queue.sync {
for i in 0..<10 {
print("", i)
}
}
for i in 100..<110 {
print("Ⓜ️", i)
}
}
//This will print asynchronously
func simpleQueues() {
let queue = DispatchQueue(label: "com.appcoda.myqueue")
queue.async {
for i in 0..<10 {
print("", i)
}
}
for i in 100..<110 {
print("Ⓜ️", i)
}
}
Swift 3 は新しいDispatchQueue
クラスを利用してキューとスレッドを管理します。バックグラウンド スレッドで何かを実行するには、以下を使用します。
let backgroundQueue = DispatchQueue(label: "com.app.queue", qos: .background)
backgroundQueue.async {
print("Run on background thread")
}
または、2 行のコードで何かが必要な場合:
DispatchQueue.global(qos: .background).async {
print("Run on background thread")
DispatchQueue.main.async {
print("We finished that.")
// only back on the main thread, may you access UI:
label.text = "Done."
}
}
このチュートリアルで、Swift 3 の GDC に関する詳細な情報を入手することもできます。
バックグラウンドで実行する変更と、UI で実行する更新を分離する必要があります。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// do your task
dispatch_async(dispatch_get_main_queue()) {
// update some UI
}
}
とにかく良い答えですが、オブジェクト指向ソリューションUp to date for swift 5を共有したいと思います。
それをチェックしてください: AsyncTask
Android の AsyncTask に概念的に着想を得て、Swift で独自のクラスを作成しました。
AsyncTaskを使用すると、UI スレッドを適切かつ簡単に使用できます。このクラスを使用すると、バックグラウンド操作を実行し、UI スレッドで結果を公開できます。
ここにいくつかの使用例があります
例 1 -
AsyncTask(backgroundTask: {(p:String)->Void in//set BGParam to String and BGResult to Void
print(p);//print the value in background thread
}).execute("Hello async");//execute with value 'Hello async'
例 2 -
let task2=AsyncTask(beforeTask: {
print("pre execution");//print 'pre execution' before backgroundTask
},backgroundTask:{(p:Int)->String in//set BGParam to Int & BGResult to String
if p>0{//check if execution value is bigger than zero
return "positive"//pass String "poitive" to afterTask
}
return "negative";//otherwise pass String "negative"
}, afterTask: {(p:String) in
print(p);//print background task result
});
task2.execute(1);//execute with value 1
2 つの一般的なタイプがあります。
BGParam
- 実行時にタスクに送信されるパラメーターのタイプ。
BGResult
- バックグラウンド計算の結果のタイプ。
AsyncTask を作成すると、バックグラウンド タスクに出入りする必要があるものにこれらの型を渡すことができますが、それらの型が必要ない場合は、単に次のように設定するVoid
か、または短い構文を使用して、未使用としてマークできます。()
非同期タスクが実行されると、次の 3 つの手順が実行されます。
beforeTask:()->Void
タスクが実行される直前に UI スレッドで呼び出されます。backgroundTask: (param:BGParam)->BGResult
直後にバックグラウンド スレッドで呼び出されるafterTask:(param:BGResult)->Void
バックグラウンド タスクの結果を使用して UI スレッドで呼び出される私はDan Beaulieuの答えが本当に好きですが、Swift 2.2では機能せず、それらの厄介な強制アンラップを回避できると思います!
func backgroundThread(delay: Double = 0.0, background: (() -> Void)? = nil, completion: (() -> Void)? = nil) {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)) {
background?()
if let completion = completion{
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
dispatch_after(popTime, dispatch_get_main_queue()) {
completion()
}
}
}
}