我正在为macOS写一个Swift应用程序,它可以叠加图像.

我试着创建一个小项目来读取一幅图像,并将其写入1000次.

我使用DispatchQueue.全局,使UI可以自由显示操作编号.

如果你有任何 idea ;)

谢谢

代码如下:

import SwiftUI

struct ContentView: View {
    
    @State private var presentImageImporter = false
    @State private var runningComputation = 1
    @State private var inputImage: NSImage?
    
    var body: some View {
        
        VStack {
            
            Button("Image") {
                presentImageImporter = true
            }.fileImporter(isPresented: $presentImageImporter, allowedContentTypes: [.png, .jpeg]) { result in
                switch result {
                    case .success(let url):
                        if url.startAccessingSecurityScopedResource() {
                               inputImage = NSImage(byReferencing: url)
                            url.stopAccessingSecurityScopedResource()
                        }
                    case .failure(let error):
                        print(error)
                }
            }
            
            Button("Compute 1000 read image") {
                runComputations()
            }
            Divider()
            Text("\(runningComputation)")
            Divider()
        }.frame(minWidth: 200, minHeight: 200)
    }
    
    func runComputations() {
        
                
            let downloadDir = try! FileManager.default.url(
                for: FileManager.SearchPathDirectory.downloadsDirectory,
                in: FileManager.SearchPathDomainMask.userDomainMask,
                appropriateFor: nil,
                create: true)
            
            let subFolder = downloadDir.appendingPathComponent("toto")
        
            try! FileManager.default.createDirectory(at: subFolder, withIntermediateDirectories: true)
            
            DispatchQueue.global(qos: .userInitiated).async {
                for i in 0...1000 {
                    
                    writePNG(inputImage!, url: subFolder.appendingPathComponent("image\(i).png"))
                    
                    runningComputation += 1
                }
            }
            
       
    }
    
}

func writePNG(_ image: NSImage, url: URL) {
    let newRep = NSBitmapImageRep(data: image.tiffRepresentation!)
    newRep!.size = image.size
    let pngData = newRep!.representation(using: .png, properties: [:])
    
    do {
        try pngData!.write(to: url)
    } catch {
        print(error)
    }
}

和跟踪图像

Trace

推荐答案

问题在于:

for i in 0...1000 {
    writePNG(inputImage!, url: subFolder.appendingPathComponent("image\(i).png"))                    
    runningComputation += 1
}

这是在不耗尽自动释放池的情况下创建大量临时自动释放对象.您会注意到,在运行结束时,内存使用量突然下降到8MB.此时默认的自动释放池将耗尽.

您需要将每个迭代封装在其自己的autoreleasepool块中,以便更快地丢弃临时对象.

for i in 0...1000 {
    autoreleasepool {
        writePNG(inputImage!, url: subFolder.appendingPathComponent("image\(i).png"))                    
        runningComputation += 1
    }
}

Swift相关问答推荐

为什么在Swift属性Wrapper中需要类型注释?

如何禁用MacOS上SwiftUI中按钮周围的聚焦环(或高亮显示)?

字符串目录不适用于SWIFT包

在Swift中,是否只有iOS版本超过15才能导入Swift包?

OBJC代码中Swift 演员的伊瓦尔:原子还是非原子?

阻塞(受CPU限制的)任务的异步功能?

UICollectionViewCompostionalLayout Collectionview单元格宽度在重新加载数据后未正确调整大小

从任务中打印

如何在闭包中使用构造 await sync

如何在 SwiftUI 中创建条件内容?

如何为等待函数调用添加超时

swift 是否遇到 Java 的 2gb 最大序列化大小问题?

如何在 UITableView 中点击图片和标题

如何使 SwiftUI Picker 换行文本

异步等待不会在项目中触发,但在 Xcode playground 中工作正常

如何自己快速编写 Hashable 协议

swift中的SequenceType和CollectionType有什么区别?

Swift 自定义字体 Xcode

如何发送静默推送通知有效负载

判断用户是否登录到 iCloud?Swift /iOS