对于这个问题有很多答案,但我不明白它们之间的某些具体区别,所以我会发布我需要的内容然后提问。
关于我的项目:
我有一个效果添加高斯模糊和这样的事情的图像,内存优化得很好。当我保存图像时,最后一步是在UITableView
上显示它们。图像数量将从30到60.如果我捕获高质量图像内存将高达200 MB,因此UITableView
当然会添加额外的内存。 (会被破坏!)。此时我在CoreData
中保存图像,在UITableView之前我生成缩略图以减少内存。
我的问题:
而不是使用CoreData
更好地在本地保存图像?它将有助于UITableView
它将如何影响记忆?
感谢。
答案 0 :(得分:1)
我更喜欢在本地保存图像,在Documents目录中,然后在Core Data中存储图像的路径。我不认为将图像作为二进制文件存储在Core Data中,而不是将其保存在磁盘上,因为您永远不会根据其二进制属性获取对象。
此外,我认为从磁盘加载图像比从二进制加载图像更快。我发现imageWithData:
在逐步从网络上下载大图时非常有用。
您还可以查看this article,看看imageWithContentsOfFile:
的内存占用量很小。
答案 1 :(得分:1)
感谢您的要点,我有一些关于如何以更清洁的方式实现它的建议。 这当然是未经测试的代码,只能用作灵感。
我们的想法是拥有一个更干净的cellForRowAtIndexPath,并尝试使用已设置数据的模型列表。这样UITableViewDataSource只读取现有数据。这保证了良好的性能。因此,在下载数据之后,尝试制作它的模型,稍后在UITableViewDataSource方法中使用它们,例如" cellForRowAtIndexPath"和" numberOfRowsInSection"
未经测试的代码中真正需要清理的是您从下载的数据创建模型的方式/时间。你可以同时下载所有数据,然后将所有对象转换为模型,然后重新加载tableview吗?
class MyViewController: UIViewController {
// The UITableViewDataSource class contains a list TimeLineCellModels, which is used in numberOfRowsInSection
var models: [TimeLineCellModel] = []
//MARK: - Private Methods
func addModel() {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { () -> Void in
var imageDataFinal = task.document
var finalImage = UIImage(data: imageDataFinal as NSData)
let size = CGSizeApplyAffineTransform(finalImage!.size, CGAffineTransformMakeScale(0.2, 0.2))
let hasAlpha = false
let scale: CGFloat = 0.0 // Automatically use scale factor of main screen
UIGraphicsBeginImageContextWithOptions(size, !hasAlpha, scale)
finalImage!.drawInRect(CGRect(origin: CGPointZero, size: size))
let scaledImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
var model = TimeLineCellModel(task.documentName, documentDateString: task.createdOn, documentImage, scaledImage)
self.models.append(model)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
})
}
private func modelForIndexPath(indexPath: NSIndexPath) -> TimeLineCellModel {
return models[indexPath.row]
}
//MARK: - UITableViewDataSource Methods
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as! TimeLineCell
let model = modelForIndexPath(indexPath)
cell.updateWithModel(task)
return cell
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let rowCount = models.count
return rowCount
}
}
class TimeLineCell: UITableViewCell {
@IBOutlet weak var documentName: UILabel!
@IBOutlet weak var documentDate: UILabel!
@IBOutlet weak var documentImage: UIImageView!
func updateWithModel(model: TimeLineCellModel) {
documentImage.image = model.documentImage
documentName.text = model.documentName
documentDate.text = "Created On: \(model.documentDateString)"
}
}
class TimeLineCellModel {
var documentName: String
var documentDateString: String
var documentImage: UIImage
init(documentName: String, documentDateString: String, documentImage: UIImage) {
self.documentName = documentName
self.documentDateString = documentDateString
self.documentImage = documentImage
}
}
答案 2 :(得分:0)
将图像保存为离线是否很重要?在我看来,CoreData的目的是什么。
你如何获取图像?
我建议您使用Cocoapods并添加AFNetworking并查看this category (extension) for UIImageView,这样可以轻松获取图片,并启用缓存。这是你想要的性能。 (由于AFNetworking是一个Objective-C库,不要忘记在bridging header file中导入.h文件)
你是如何模糊图像的?你在使用FXBlurView吗?所有图像都模糊了吗?这里的问题是只缓存原始图像,但在UITableView中滚动时模糊会生效,这对性能不利。
你是如何将你的UITableViewCells出列的?你能粘贴“cellForRowAtIndexPath”吗?也许您可以将模糊图像存储在模型数组中,您可以使用它来填充UITableViewCells,因此当返回单元格时,您可以使用这个“手动缓存”的模糊图像?
编辑:抱歉,上面提出的解决方案仍然使用内存,这就是你说的不起作用。使用其他用户建议的Document目录可能是最好的解决方案吗?我认为CoreData在代码量甚至性能方面引入了相当大的开销?