首页
学习
活动
专区
圈层
工具
发布

在Swift中,我有一个函数可以递归地复制文件夹,并使用异步调用。我想添加一个完成处理程序。有什么优雅的解决方案吗?

在Swift中,如果你想要递归地复制文件夹并使用异步调用,同时添加一个完成处理程序,你可以使用DispatchGroup来跟踪所有的异步任务,并在所有任务完成后执行完成处理程序。以下是一个示例代码,展示了如何实现这一功能:

代码语言:txt
复制
import Foundation

func copyFolder(at srcURL: URL, to dstURL: URL, completion: @escaping () -> Void) {
    let fileManager = FileManager.default
    let group = DispatchGroup()

    func copyItem(at srcURL: URL, to dstURL: URL) {
        group.enter()
        DispatchQueue.global(qos: .userInitiated).async {
            do {
                if fileManager.fileExists(atPath: dstURL.path) {
                    try fileManager.removeItem(at: dstURL)
                }
                try fileManager.copyItem(at: srcURL, to: dstURL)
            } catch {
                print("Failed to copy item at \(srcURL) to \(dstURL): \(error)")
            }
            group.leave()
        }
    }

    func copyFolderContents(at srcURL: URL, to dstURL: URL) {
        do {
            let contents = try fileManager.contentsOfDirectory(at: srcURL, includingPropertiesForKeys: nil, options: [])
            for item in contents {
                let dstItemURL = dstURL.appendingPathComponent(item.lastPathComponent)
                if item.hasDirectoryPath {
                    try fileManager.createDirectory(at: dstItemURL, withIntermediateDirectories: true, attributes: nil)
                    copyFolderContents(at: item, to: dstItemURL)
                } else {
                    copyItem(at: item, to: dstItemURL)
                }
            }
        } catch {
            print("Failed to copy folder contents at \(srcURL) to \(dstURL): \(error)")
        }
    }

    group.enter()
    DispatchQueue.global(qos: .userInitiated).async {
        do {
            if !fileManager.fileExists(atPath: dstURL.path) {
                try fileManager.createDirectory(at: dstURL, withIntermediateDirectories: true, attributes: nil)
            }
            copyFolderContents(at: srcURL, to: dstURL)
        } catch {
            print("Failed to create destination folder at \(dstURL): \(error)")
        }
        group.leave()
    }

    group.notify(queue: .main) {
        completion()
    }
}

// 使用示例
let srcFolderURL = URL(fileURLWithPath: "/path/to/source/folder")
let dstFolderURL = URL(fileURLWithPath: "/path/to/destination/folder")

copyFolder(at: srcFolderURL, to: dstFolderURL) {
    print("Folder copied successfully.")
}

解释

  1. DispatchGroup: 这个类用于跟踪一组任务的完成情况。你可以调用enter()来标记一个任务的开始,并在任务完成时调用leave()。当所有的enter()调用都有对应的leave()调用时,notify(queue:execute:)方法会被触发。
  2. 异步复制: 使用DispatchQueue.global(qos: .userInitiated).async来在全局队列上异步执行复制操作,这样可以避免阻塞主线程。
  3. 递归复制: copyFolderContents(at:to:)函数会递归地遍历源文件夹中的所有内容,并对每个文件或子文件夹调用copyItem(at:to:)或自身。
  4. 完成处理程序: 在所有的复制任务完成后,group.notify(queue: .main) { completion() }会在主线程上调用传入的completion闭包。

这种方法确保了所有的复制操作都是异步执行的,并且在所有操作完成后,会调用完成处理程序,从而提供了一个优雅的解决方案。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

没有搜到相关的文章

领券