383

スウィフトでスレッドを使用するには?

dispatchOnMainThread:^{

    NSLog(@"Block Executed On %s", dispatch_queue_get_label(dispatch_get_current_queue()));

}];
4

17 に答える 17

163

swift5 での Dan Beaulieu の回答 (Swift 3.0.1 以降も機能)。

スウィフト 5.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
})
于 2016-12-06T14:25:21.737 に答える
49

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)
    }
}
于 2018-08-16T12:51:11.293 に答える
49

スウィフト 3 バージョン

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 に関する詳細な情報を入手することもできます。

于 2016-06-16T15:13:23.300 に答える
22

バックグラウンドで実行する変更と、UI で実行する更新を分離する必要があります。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    // do your task

    dispatch_async(dispatch_get_main_queue()) {
        // update some UI
    }
}
于 2015-07-07T08:38:20.487 に答える
9

とにかく良い答えですが、オブジェクト指向ソリューション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 つの手順が実行されます。

  1. beforeTask:()->Voidタスクが実行される直前に UI スレッドで呼び出されます。
  2. backgroundTask: (param:BGParam)->BGResult直後にバックグラウンド スレッドで呼び出される
  3. afterTask:(param:BGResult)->Voidバックグラウンド タスクの結果を使用して UI スレッドで呼び出される
于 2016-02-04T18:52:04.530 に答える
1

私は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()
            }
        }
    }
}
于 2016-05-03T13:55:59.260 に答える