我遇到了使用swift将数据导入coredata项目的问题。 我正在导入大量图像,这导致相当大的内存占用(大约100 - 120MB)。问题是,一旦下载并导入了图像,我保存了managedObjectContext并重置它,但是内存没有被释放。但是,如果我将应用程序发送到后台,大部分内存都会被释放(我最终会得到~50MB)。
我使用以下CoreData设置:
masterContext
PrivateQueueConcurrencyType
mainContext
MainQueueConcurrencyType
和masterContext
为parentContext
PrivateQueueConcurrencyType
和mainContext
parentContext
的{{1}} 以下方法开始导入:
func downloadProductImages(completion: (error: NSError?) -> Void) {
if let moc = self.backgroundMOC {
moc.performBlock { () -> Void in
moc.reset()
var err: NSError? = nil
self.importBrandImages({ (error) -> Void in
if error != nil {
completion(error: error)
return
}
moc.save(nil)
self.importProductVariantThumbnails({ (error) -> Void in
if error != nil {
completion(error: error)
return
}
moc.save(nil)
moc.reset()
self.backgroundMOC = nil
completion(error: err)
})
})
}
}
}
这些方法下载图像并将其保存在数据库中:
private func importBrandImages(completion: (error: NSError?) -> Void) {
if let moc = self.backgroundMOC {
moc.performBlock { () -> Void in
moc.reset()
var error: NSError? = nil
let brandsFetchReq = NSFetchRequest(entityName: "Brand")
// brand images
if let brands = moc.executeFetchRequest(brandsFetchReq, error: &error) as? [Brand] {
let imageQueue = TaskQueue()
autoreleasepool({ () -> () in
for brand in brands {
if let logoSrc = brand.logoSrc {
imageQueue.tasks +=~ { results, next in
ImageLoader.sharedLoader.imageForUrl(logoSrc.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!, completionHandler: { (image, url) -> () in
if image != nil {
brand.logo = UIImageJPEGRepresentation(image, 0.35)
}
next(nil)
})
}
}
if let bgImgSrc = brand.bgImageSrc {
imageQueue.tasks +=~ { results, next in
ImageLoader.sharedLoader.imageForUrl(bgImgSrc.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!, completionHandler: { (image, url) -> () in
if image != nil {
brand.bgImage = UIImageJPEGRepresentation(image, 0.35)
}
next(nil)
})
}
}
}
})
imageQueue.run(completion: { () -> Void in
moc.save(nil)
completion(error: error)
})
} else {
completion(error: error)
}
}
}
}
private func importProductVariantThumbnails(completion: (error: NSError?) -> Void) {
var err: NSError? = nil
if let moc = self.backgroundMOC {
moc.performBlock { () -> Void in
moc.reset()
let pVariantsFetchReq = NSFetchRequest(entityName: "ProductVariant")
if let variants = moc.executeFetchRequest(pVariantsFetchReq, error: &err) as? [ProductVariant] {
let importQueue = TaskQueue()
autoreleasepool({ () -> () in
for variant in variants {
if let thumbnailSrc = variant.thumbnailSrc {
importQueue.tasks +=~ { results, next in
ImageLoader.sharedLoader.imageForUrl(thumbnailSrc.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!, completionHandler: { (image, url) -> () in
if image != nil {
variant.thumbnail = UIImageJPEGRepresentation(image, 0.35)
}
next(nil)
})
}
}
}
})
importQueue.run { () -> Void in
moc.save(nil)
self.importProductVariantImages({ (error) -> Void in
completion(error: error)
})
}
}
}
}
}
private func importProductVariantImages(completion: (error: NSError?) -> Void) {
var error: NSError? = nil
if let moc = self.backgroundMOC {
moc.performBlock { () -> Void in
moc.reset()
let pImagesFetchReq = NSFetchRequest(entityName: "ProductImage")
// product images
if let images = moc.executeFetchRequest(pImagesFetchReq, error: &error) as? [ProductImage] {
let importQueue = TaskQueue()
autoreleasepool({ () -> () in
for pImage in images {
if let imageSrc = pImage.imageSrc {
importQueue.tasks +=~ { results, next in
ImageLoader.sharedLoader.imageForUrl(imageSrc.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!, completionHandler: { (image, url) -> () in
if image != nil {
pImage.imageData = UIImageJPEGRepresentation(image, 0.35)
}
next(nil)
})
}
}
}
})
importQueue.run(completion: { () -> Void in
moc.save(nil)
completion(error: error)
})
} else {
completion(error: error)
}
}
}
}
我不知道,为什么没有释放内存。我使用Instruments来查找内存泄漏,但它没有显示任何内容。
答案 0 :(得分:1)
您的问题似乎是ImageLoader
包含缓存并且正在向其添加所有图像。如果您不需要该功能,并且它看起来并不像您那样,那么您应该将其删除并简化ImageLoader
,以便下载并返回图像。