如何在后台线程swift中运行for循环

Posted

技术标签:

【中文标题】如何在后台线程swift中运行for循环【英文标题】:How to run for loop in background thread swift 【发布时间】:2017-07-18 12:43:51 【问题描述】:

我正在使用 for 循环来迭代照片并将其添加到核心数据中,但它在我正在使用的过程中阻塞了 UI 线程

self.fetchResult = PHAsset.fetchAssets(with: .image, options: allPhotosOptions)

DispatchQueue.main.async  

for i in 0 ..< self.fetchResult.count 
    GenericCoreData.saveEntity("Details")

【问题讨论】:

格式化和缩进代码通常会突出显示为什么事情没有按照您期望的那样做。 你确定这是你想做的事情吗?用户的照片库可以是几千兆字节。将它们复制到您的应用程序将使它们的大小加倍。您确定不想只保留图片在照片库中存储位置的网址吗? How to use background thread in swift?的可能重复 【参考方案1】:

你可以像这样使用 DispatchQueue。

DispatchQueue.global(qos: .background).async 
    for i in 0 ..< self.fetchResult.count 
       GenericCoreData.saveEntity("Details")
    

This will help you more.

【讨论】:

那么,我们可以认为这是一种改进吗? 我认为你是在 viewdidload 方法中运行它..!! 没有我调用 DispatchQueue.global(qos: .userintiated).async 中的方法 你可以通过userInitiated background联系 //DispatchQueue.global(qos: .userInitiated).async for i in 0 .. 【参考方案2】:

我也有同样的问题。在我的情况下,循环锁定了主线程。这不是从 1 -10 的简单计数,在每次迭代中,其他两个内部函数都在运行,因此 UI 被阻塞。我需要在后台运行它,然后在它完成后更新主线程上的 UI。

我使用了a background task from this answer 并为其添加了一个循环

1- 在DispatchQueue 上创建一个extension 并将此static 方法添加到其中

extension DispatchQueue 

    static func myBackground(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()
                )
            
        
    

2- 调用上述方法并在第一部分中添加循环:

DispatchQueue.myBackground(background: 

    // do something in background like run a loop in the background

    for num in 1..<10 

        // run function 1
        // run function 2 after function 1 is finished
    

, completion:

    // when background job finished, do something in main thread

)

您也可以使用的另一种方法是DispatchGroup

let dispatchGroup = DispatchGroup()

for num in 1..<10 

    // ** call this to enter the group **
    dispatchGroup.enter()

    // run function 1
    // run function 2 after function 1 is finished and call **dispatchGroup.leave()** to exit the group when function 2 is finished
    // make sure to call **dispatchGroup.leave()** or this will never end


dispatchGroup.notify(queue: .global(qos: .background)) 

    DispatchQueue.main.async  [weak self] in

        // when background job finished, do something in main thread
    

【讨论】:

以上是关于如何在后台线程swift中运行for循环的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift中使用后台线程?

如何从 Swift 的后台线程中从 CoreData 中获取未保存的数据?

iOS / Swift(UI)始终运行的后台计算线程的高效实现-GCD案例?

如何检查Android后台服务线程是不是正在运行

在后台线程内循环并不断更新 UI 时使用啥?

如何从后台线程 Swift UI GET 请求发布更改