我有以下for循环将文件从服务器下载到我的iPad 3设备。 运行数百个文件,我收到错误和应用程序崩溃。控制台显示我"收到内存警告。在我的iPad Air上运行的逻辑相同。任何人都可以提供如何解决问题。
iPad 3 - > iOS 9.3.5 iPad Air - > iOS 10.3.3
func download() {
for (index, subJson): (String, JSON) in serverJson! {
for (_, subJson): (String, JSON) in subJson {
let filepath = subJson["path"].stringValue
let nUpdated = subJson["updated"].stringValue
if let oUpdated = localJson?[index].array?.filter({ $0["path"].string == filepath}).first?["updated"].stringValue {
if (oUpdated == nUpdated)
{
DispatchQueue.main.async { () -> Void in
self.progressView.progress = Float(self.count) / Float(self.totalCount)
}
count += 1
continue
}
}
var absPath = filepath
let strIdx = absPath.index(absPath.startIndex, offsetBy: 2)
if (absPath.hasPrefix("./"))
{
absPath = absPath.substring(from: strIdx)
}
let sourceUrl = URL(string: self.sourceUrl.appending(absPath))
do {
let fileData = try NSData(contentsOf: sourceUrl!, options: NSData.ReadingOptions())
try writeFileToLocal(absPath, fileData)
} catch {
print(error)
}
DispatchQueue.main.async { () -> Void in
self.progressView.progress = Float(self.count) / Float(self.totalCount)
}
//print("Path: \(absPath)")
//print("%: \(Float(count) / Float(totalCount))")
count += 1
}
}
do {
// Remove temp json file first if exists.
if fileManager.fileExists(atPath: oldManifestPath) {
try? fileManager.removeItem(atPath: oldManifestPath)
}
// Write temp json file to local.
try data?.write(to: oldManifestUrl)
self.defaults.set(hashes, forKey: "LastHash")
} catch {
print(error)
}
DispatchQueue.main.async {
self.progressView.isHidden = true
self.changeViewProperties(2)
}
}
}
private func writeFileToLocal(_ url:String, _ data:NSData) throws {
let url = URL(string: url)
let path = url?.deletingLastPathComponent().relativePath
let file = url?.lastPathComponent
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
let filePath = documentsPath.appendingPathComponent(path!)
var isDir: ObjCBool = false
if !FileManager.default.fileExists(atPath: (filePath?.path)!, isDirectory:&isDir) {
try FileManager.default.createDirectory(atPath: filePath!.path, withIntermediateDirectories: true, attributes: nil)
}
FileManager.default.changeCurrentDirectoryPath((filePath?.path)!)
try data.write(toFile: file!, options: .atomicWrite)
print("Update: \(filePath!), \(file!)")
FileManager.default.changeCurrentDirectoryPath(documentsPath.path!)
}
然后我调用函数"下载"在DispatchQueue。
DispatchQueue.global().async {
self.downloadFiles()
}
答案 0 :(得分:0)
当您在主线程上处理数百件物品时,就会发生内存警告,如果它可以帮助您在后台队列而不是主队列中使用该功能,那么您可以试用它,您可能会得到一些您需要的ui警告在后台线程中管理为更新ui
我不知道它是否会对你有所帮助,但你只需尝试一次
DispatchQueue.global(qos: .background).async
{
//BackGround Queue Update
self.downloadFiles()
DispatchQueue.main.async
{
//Main Queue Update With All UI
}
}
作为后台线程总是很好管理巨大的处理,例如翠鸟库在主线程上获取数据并在主线程上返回但在后台线程中处理它