Ios 如何在swift中使用背景线程?
如何在swift中使用线程Ios 如何在swift中使用背景线程?,ios,swift,multithreading,dispatch-queue,Ios,Swift,Multithreading,Dispatch Queue,如何在swift中使用线程 dispatchOnMainThread:^{ NSLog(@"Block Executed On %s", dispatch_queue_get_label(dispatch_get_current_queue())); }]; 从 Swift 2 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { //All stuff here })
dispatchOnMainThread:^{
NSLog(@"Block Executed On %s", dispatch_queue_get_label(dispatch_get_current_queue()));
}];
从
Swift 2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
//All stuff here
})
Swift 3.0+
在Swift 3.0中已经有很多内容。在后台队列上运行某些内容如下所示:
DispatchQueue.global(qos: .userInitiated).async {
print("This is run on a background queue")
DispatchQueue.main.async {
print("This is run on the main queue, after the previous code in outer block")
}
}
Swift 1.2至2.3
Swift前1.2–已知问题
在Swift 1.1版本中,苹果不支持上述语法,除非进行一些修改。传递QOS\u CLASS\u USER\u INITIATED
实际上不起作用,而是使用Int(QOS\u CLASS\u USER\u INITIATED.value)
有关更多信息,请参见最佳做法是定义可多次访问的可重用函数 可重用功能: e、 g.像AppDelegate.swift这样的全局函数
func backgroundThread(_ delay: Double = 0.0, background: (() -> Void)? = nil, completion: (() -> Void)? = nil) {
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.value), 0)) {
background?()
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
dispatch_after(popTime, dispatch_get_main_queue()) {
completion?()
}
}
}
注意:在Swift 2.0中,将上面的QOS\u CLASS\u USER\u INITIATED.value替换为QOS\u CLASS\u USER\u INITIATED.rawValue
用法:
A.要在后台以3秒的延迟运行进程:
backgroundThread(3.0, background: {
// Your background function here
})
B.在后台运行流程,然后在前台运行完成:
backgroundThread(background: {
// Your function here to run in the background
},
completion: {
// A function to run in the foreground when the background thread is complete
})
C.延迟3秒-注意,在没有背景参数的情况下使用完成参数:
backgroundThread(3.0, completion: {
// Your delayed function here to be run in the foreground
})
您必须将要在后台运行的更改与要在UI上运行的更新分开:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
// do your task
dispatch_async(dispatch_get_main_queue()) {
// update some UI
}
}
不过答案很好,无论如何,我想分享我的面向对象解决方案最新的swift 5 请查看: 从概念上讲,受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
它有两种通用类型:
-执行时发送到任务的参数类型BGParam
-背景计算结果的类型 创建AsyncTask时,可以将这些类型转换为需要传入或传出后台任务的任何类型,但如果不需要这些类型,可以将其标记为未使用,只需将其设置为:BGResult
或使用更短的语法:Void
()
beforeTask:()->Void
在执行任务之前在UI线程上调用backgroundTask:(param:BGParam)->bgfresult
之后立即在后台线程上调用后任务:(param:bgfresult)->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()
}
}
}
}
Swift 3版本
Swift 3利用新的DispatchQueue
类来管理队列和线程。要在后台线程上运行某些内容,请使用:
let backgroundQueue = DispatchQueue(label: "com.app.queue", qos: .background)
backgroundQueue.async {
print("Run on background thread")
}
或者,如果您需要两行代码:
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的深入信息。Dan Beaulieu在Swift 5中的回答(自Swift 3.0.1起也起作用) Swift 5.0.1 用法
由于上面已经回答了OP问题,我只想补充一些速度方面的考虑: 我不建议运行具有.background线程优先级的任务,尤其是在iPhone X上,因为任务似乎分配在低功耗内核上 以下是计算密集型函数中的一些实际数据,该函数从XML文件(带缓冲)读取数据并执行数据插值: 设备名称/.background/.utility/.default/.userInitiated/.userInteractive
请注意,并非所有设备的数据集都相同。它在iPhone X上是最大的,在iPhone 5s上是最小的。Grand Central Dispatch用于在我们的iOS应用程序中处理多任务 您可以使用此代码
// Using time interval
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+1) {
print("Hello World")
}
// Background thread
queue.sync {
for i in 0..<10 {
print("Hello", i)
}
}
// Main thread
for i in 20..<30 {
print("Hello", i)
}
//使用时间间隔
DispatchQueue.main.asyncAfter(截止日期:DispatchTime.now()+1){
打印(“你好世界”)
}
//背景线程
queue.sync{
对于Swift 4.2和Xcode 10.1中的0..中的i
我们有三种类型的队列:
1.主队列:
主队列是由系统创建并与应用程序主线程关联的串行队列
2.全局队列:
全局队列是一个并发队列,我们可以根据任务的优先级请求它
3.自定义队列:可由用户创建。通过指定服务质量属性(QoS),自定义并发队列始终映射到全局队列之一
所有这些队列都可以通过两种方式执行
1.同步执行
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()
})
2.异步执行
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()
})
来自AppCoda:
//这将同步打印意味着,它将打印1-9和100-109
func simpleQueues(){
let queue=DispatchQueue(标签:“com.appcoda.myqueue”)
queue.sync{
对于0中的i..Swift 4.x
将其放入某个文件:
background {
//background job
main {
//update UI (or what you need to do in main thread)
}
}
然后在需要的地方调用它:
import Foundation
class myThread: Thread
{
override func main() {
while(true) {
print("Running in the Thread");
Thread.sleep(forTimeInterval: 4);
}
}
}
let t = myThread();
t.start();
while(true) {
print("Main Loop");
sleep(5);
}
在Swift 4.2中,这起作用
public enum QueueType {
case Main
case Background
case LowPriority
case HighPriority
var queue: DispatchQueue {
switch self {
case .Main:
return DispatchQueue.main
case .Background:
return DispatchQueue(label: "com.app.queue",
qos: .background,
target: nil)
case .LowPriority:
return DispatchQueue.global(qos: .userInitiated)
case .HighPriority:
return DispatchQueue.global(qos: .userInitiated)
}
}
}
func performOn(_ queueType: QueueType, closure: @escaping () -> Void) {
queueType.queue.async(execute: closure)
}
线程的多用途函数
performOn(.Background) {
//Code
}
像这样使用它:
import Foundation
typealias Dispatch = DispatchQueue
extension Dispatch {
static func background(_ task: @escaping () -> ()) {
Dispatch.global(qos: .background).async {
task()
}
}
static func main(_ task: @escaping () -> ()) {
Dispatch.main.async {
task()
}
}
}
Swift 5
为方便起见,请创建一个包含以下内容的文件“DispatchQueue+Extensions.swift”:
Dispatch.background {
// do stuff
Dispatch.main {
// update UI
}
}
用法:
转换哪个部分有困难?为什么在最后一行分号之前有]
呢?如果您能解释一下您遇到了什么问题或需要帮助,这会很有帮助。如果正确的答案确实对您有帮助,您必须接受,这也会帮助其他人找到正确的解决方案。DispatchQueue.global(qos:.background).async{print(“在后台线程上运行”)DispatchQueue.main.async{print(“我们完成了它”)//只有bac
import Foundation
class myThread: Thread
{
override func main() {
while(true) {
print("Running in the Thread");
Thread.sleep(forTimeInterval: 4);
}
}
}
let t = myThread();
t.start();
while(true) {
print("Main Loop");
sleep(5);
}
public enum QueueType {
case Main
case Background
case LowPriority
case HighPriority
var queue: DispatchQueue {
switch self {
case .Main:
return DispatchQueue.main
case .Background:
return DispatchQueue(label: "com.app.queue",
qos: .background,
target: nil)
case .LowPriority:
return DispatchQueue.global(qos: .userInitiated)
case .HighPriority:
return DispatchQueue.global(qos: .userInitiated)
}
}
}
func performOn(_ queueType: QueueType, closure: @escaping () -> Void) {
queueType.queue.async(execute: closure)
}
performOn(.Background) {
//Code
}
import Foundation
typealias Dispatch = DispatchQueue
extension Dispatch {
static func background(_ task: @escaping () -> ()) {
Dispatch.global(qos: .background).async {
task()
}
}
static func main(_ task: @escaping () -> ()) {
Dispatch.main.async {
task()
}
}
}
Dispatch.background {
// do stuff
Dispatch.main {
// update UI
}
}