我有一个很大的困难是一个星期。我得到一个包含许多对象的JSON,每个对象最多可以获得8张照片。我正在进行基于15,000个对象的测试,直到我收到错误"Malloc error “can't allocate region” failed with error code 3"
我该如何解决这个问题?我试图重置我的核心对象日期的上下文,但也没有决定。
下面我提出了我的部分代码:
for item in products {
i = i + 1
print(i)
let p = item as! NSDictionary
let product = NSEntityDescription.insertNewObjectForEntityForName("PRODUCT", inManagedObjectContext: self.context) as! PRODUCT
if tipo != "FULL"{
let chave = p["Chave"] as! String
if self.loadProductWithKey(chave).count > 0 {
self.deleteProductWithKey(chave)
}
}
product.chave = p["Chave"] as? String
product.chaveFabricante = p["ChaveFabricante"] as? String
product.chaveMarca = p["ChaveMarca"] as? String
product.chaveUnidade = p["ChaveUnidade"] as? String
product.chaveGrupo = p["ChaveGrupo"] as? String
product.codigo = p["Codigo"] as? String
product.codigoSegundario = p["CodigoSecundario"] as? String
product.descricaoNF = p["DescricaoNf"] as? String
product.descricaoDetalhada = p["DescricaoDetalhada"] as? String
product.chaveLicenca = p["ChaveLicenca"] as? String
var image = UIImage()
var url = NSURL()
var code = ""
var chave = ""
var fileName = ""
let photo1Url = p["UrlFoto1"] as! String
if photo1Url != ""{
url = NSURL(string: "\(_URLPREFIX)\(photo1Url)")!
if let foto = NSData(contentsOfURL: url) {
if foto.length > 0{
image = UIImage(data: foto)!
code = p["Codigo"] as! String
chave = p["Chave"] as! String
let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
fileName = "picture-\(chave)-\(code)-1.jpg"
let fileURL = documents.URLByAppendingPathComponent(fileName)
if let jpgImageData = UIImageJPEGRepresentation(image, 0.8) {
jpgImageData.writeToURL(fileURL, atomically: true)
}
product.urlFoto1 = fileName
}
}
}
let photo2Url = p["UrlFoto2"] as! String
if photo2Url != ""{
url = NSURL(string: "\(_URLPREFIX)\(photo2Url)")!
if let foto = NSData(contentsOfURL: url) {
if foto.length > 0{
image = UIImage(data: foto)!
code = p["Codigo"] as! String
chave = p["Chave"] as! String
let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
fileName = "picture-\(chave)-\(code)-2.jpg"
let fileURL = documents.URLByAppendingPathComponent(fileName)
if let jpgImageData = UIImageJPEGRepresentation(image, 0.8) {
jpgImageData.writeToURL(fileURL, atomically: true)
}
product.urlFoto2 = fileName
}
}
}
let photo3Url = p["UrlFoto3"] as! String
if photo3Url != ""{
url = NSURL(string: "\(_URLPREFIX)\(photo3Url)")!
if let foto = NSData(contentsOfURL: url) {
if foto.length > 0{
image = UIImage(data: foto)!
code = p["Codigo"] as! String
chave = p["Chave"] as! String
let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
fileName = "picture-\(chave)-\(code)-3.jpg"
let fileURL = documents.URLByAppendingPathComponent(fileName)
if let jpgImageData = UIImageJPEGRepresentation(image, 0.8) {
jpgImageData.writeToURL(fileURL, atomically: true)
}
product.urlFoto3 = fileName
}
}
}
let photo4Url = p["UrlFoto4"] as! String
if photo4Url != ""{
url = NSURL(string: "\(_URLPREFIX)\(photo4Url)")!
if let foto = NSData(contentsOfURL: url) {
if foto.length > 0{
image = UIImage(data: foto)!
code = p["Codigo"] as! String
chave = p["Chave"] as! String
let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
fileName = "picture-\(chave)-\(code)-4.jpg"
let fileURL = documents.URLByAppendingPathComponent(fileName)
if let jpgImageData = UIImageJPEGRepresentation(image, 0.8) {
jpgImageData.writeToURL(fileURL, atomically: true)
}
product.urlFoto4 = fileName
}
}
}
let photo5Url = p["UrlFoto5"] as! String
if photo5Url != ""{
url = NSURL(string: "\(_URLPREFIX)\(photo5Url)")!
if let foto = NSData(contentsOfURL: url) {
if foto.length > 0{
image = UIImage(data: foto)!
code = p["Codigo"] as! String
chave = p["Chave"] as! String
let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
fileName = "picture-\(chave)-\(code)-5.jpg"
let fileURL = documents.URLByAppendingPathComponent(fileName)
if let jpgImageData = UIImageJPEGRepresentation(image, 0.8) {
jpgImageData.writeToURL(fileURL, atomically: true)
}
product.urlFoto5 = fileName
}
}
}
do {
try self.context.save()
} catch {
print("============ erro nos produtos")
}
self.context.refreshAllObjects()
}
答案 0 :(得分:1)
您的代码存在许多问题。
您不应使用NSData(contentsOfURL:)
从远程站点加载数据。它冻结了主线程。而是使用NSURLSession
。您可以创建一个下载任务,将您的图像数据直接下载到文件。它会异步执行,不会阻塞主线程。
您也不应该在循环中加载大量大对象而不采取措施以避免内存不足。将部件包含在循环内,在autoreleasepool
块中加载大对象:
for (i, item) in products.enumerate() {
autoreleasepool {
//Put the body of your for loop here
}
}
autoreleasepool{}
块告诉编译器它应该释放每次退出大括号时在大括号内分配的临时(或自动释放)对象。 (这被称为“耗尽自动释放池”)
通过在for循环中放置一个autoreleasepool{}
块,可以释放代码在每次循环中创建的自动释放对象。
但是,如果您使用NSURLSession
和下载任务,则无需担心。系统将下载文件并自动保存,并为您管理进程的内存。