【问题标题】:Memory Problems with UIImage(contentsOfFile)UIImage(contentsOfFile)的内存问题
【发布时间】:2016-08-05 07:47:52
【问题描述】:

我有一个集合视图,我从我的文档目录中加载一些图像:

func reloadNotesFromStore() {
    {

        let fetchRequest = NSFetchRequest(entityName: "TaskDraw")

        let formsPredicate = NSPredicate(format: "task_id = %@", self.task_id)
        fetchRequest.predicate = formsPredicate

        let sortDescriptor = NSSortDescriptor(key: "createdAt", ascending: false)
        let sortDescriptors = [sortDescriptor]
        fetchRequest.sortDescriptors = sortDescriptors

        self.photos.removeAll(keepCapacity: false)

        let taskDrawings = (try! context.executeFetchRequest(fetchRequest)) as! [TaskDraw]

        let path = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL

        for taskDraw in taskDrawings {

            let imageFilename = "\(taskDraw.remoteID!)_combined.png"
            let imageFullPath = path.URLByAppendingPathComponent("\(self.task_id)/\(imageFilename)")

            // create combined image to display
            let photo = Photo(image: UIImage(contentsOfFile: imageFullPath.path!)!)

            photo.selected = false
            photo.taskDraw = taskDraw

            self.photos.append(photo)
        }

        } ~> {
            self.collectionView?.reloadData()
    }

}

每次显示我的 CollectionViewController 时,我的内存使用量都会增加大约 30 MB。

我使用 UIImage(contentsOfFile) 加载的图像大约 150 kb。

好的,没有尝试 Leos 解决方案,但仍然没有成功。当生病重新加载我的控制器(模态)时,我的内存总是增加大约 30-40 MB。

func reloadNotesFromStore() {
    {

        let fetchRequest = NSFetchRequest(entityName: "TaskDraw")

        let formsPredicate = NSPredicate(format: "task_id = %@", self.task_id)
        fetchRequest.predicate = formsPredicate

        let sortDescriptor = NSSortDescriptor(key: "createdAt", ascending: false)
        let sortDescriptors = [sortDescriptor]
        fetchRequest.sortDescriptors = sortDescriptors

        self.items.removeAll(keepCapacity: false)

        let taskDrawings = (try! context.executeFetchRequest(fetchRequest)) as! [TaskDraw]

        let path = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0] as NSURL

        for taskDraw in taskDrawings {

            let imageFilename = "\(taskDraw.remoteID!)_combined.png"
            let imageFullPath = path.URLByAppendingPathComponent("\(self.task_id)/\(imageFilename)")

            // create combined image to display
            let collectionViewItem = CollectionViewItem()
            collectionViewItem.filePath = imageFullPath
            collectionViewItem.selected = false
            collectionViewItem.taskDraw = taskDraw

            self.items.append(collectionViewItem)
        }

        } ~> {
            self.collectionView?.reloadData()
    }

}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("PhotoCell", forIndexPath: indexPath) as! PhotoCell

    let item = items[indexPath.item]

    cell.imageView.image = UIImage(contentsOfFile: item.filePath!.path!)!
    .....

如何强制 Swift 释放我的内存? 更新2:

当生病使用 UIImage(named: ..) 而不是 UIImage(contentsOfFile: ....) 然后在第一次初始化时内存增加大约 40 MB,但是当生病关闭视图并再次加载它时保持不变(我猜发生这种情况是因为命名:.. 缓存图像)

但这也不会在关闭 VC 时释放内存。

【问题讨论】:

  • 不要将它们加载到内存中。您只需要一个带有 urls/paths 的数组
  • 所以你的意思是我应该只存储文件名,然后加载图像然后 cellForItemAtIndexPath?但是为什么当我关闭 ViewController 时我的照片数组没有被释放?
  • 是的,在准备单元格时获取图像
  • 好的,谢谢你的回答。我已经考虑过了——但我不确定为什么当我关闭 viewController 时内存没有被释放。还有为什么 iOS 需要高达 30 MB 的 RAM 来显示 3-4 个图像(大约 150kb) - 我会尝试一下。

标签: ios swift uiimage


【解决方案1】:

好的,我现在用以下解决方案解决了这个问题:

我仍然在内存中创建一个 UIImage,如下所示:

for taskDraw in taskDrawings {

       let imageFilename = "\(taskDraw.remoteID!)_combined.png"
       let imageFullPath = path.URLByAppendingPathComponent("\(self.task_id)/\(imageFilename)")

       let photo = Photo(image: UIImage(contentsOfFile: imageFullPath.path!)!.resizeToWidth(300))
       photo.taskDraw = taskDraw
       photo.addNote = false
       self.photos.append(photo)

所以只在 CollectionView 中显示调整大小的图像。 (否则我需要在磁盘上存储缩略图)

还有:

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    self.photos.removeAll(keepCapacity: false)
}

在控制器中。

现在,内存消耗非常低,并且在关闭我的 ViewController 后,使用的内存现在被释放了。

【讨论】:

    【解决方案2】:

    我在 Document 目录中有一个图像,我正在使用 UIImage(contentsOfFile:) 方法来制作 UIImage,图像存在于 DocumentDirectory 但方法返回 nil。

      let img = UIImage(contentsOfFile: ChatUtils.getPathWithFolderName(kChatAttachmentOriginalFolderName) + ("/" + fileName))
    

    【讨论】:

    • 这不是答案。
    猜你喜欢
    • 2016-03-25
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 1970-01-01
    相关资源
    最近更新 更多