【问题标题】:UIImage using contentsOfFileUIImage 使用 contentOfFile
【发布时间】:2015-06-05 06:11:00
【问题描述】:

我正在使用

self.imageView.image = UIImage(named: "foo.png")

UIIMageView 中选择和加载图像。我的应用程序中的图像位于images.xcassets 下。问题是这个特定的init 缓存了图像以便按照official Apple documentation 重复使用:

如果您有一个只显示一次的图像文件并希望 确保它不会被添加到系统的缓存中,您应该 而是使用 imageWithContentsOfFile: 创建您的图像。这会 将您的一次性图像保留在系统图像缓存之外,可能 改善应用的内存使用特性。

我的视图允许在选择图像之前循环浏览图像,因此内存占用会随着我循环浏览而不断增加,即使我从该视图返回时也不会下降。

所以我尝试使用不缓存图像的UIIMage(contentsOfFile: "path to the file")。在这里,我无法以编程方式获取存储在 images.xcassets 下的图像的路径。

我尝试过使用:

NSBundle.mainBundle().resourcePath

NSBundle.mainBundle().pathForResource("foo", ofType: "png")

没有运气。对于第一个,我得到了 resourcePath,但是通过终端访问它时,我看不到它下面的任何图像资产,第二个我在使用它时得到nil。有没有简单的方法来做到这一点?

还查看了几个 SO 问题(如 thisthisthis),但没有运气。我是否必须将图像放在其他地方才能使用pathForResource()?解决这个问题的正确方法是什么?

很难想象以前没有人遇到过这种情况:)!

【问题讨论】:

  • 为什么必须将图像存储在 images.xcassets 中?在您的情况下,似乎缺点多于优点。我宁愿将图像移动到普通文件夹并使用 pathForResource("foo", ofType: "png") 方法。
  • 所以我可以在应用目录内的文件系统中创建一个单独的文件夹来使用pathForResource()?还是我必须在 XCode 中创建一个组?
  • 您可以创建组,并在那里添加图像。请确保,该图像已复制到 Copy Bundle Resources。然后写: var bundlePath = NSBundle.mainBundle().pathForResource("imageName", ofType: "jpg") var image = UIImage(contentsOfFile: bundlePath!)
  • 谢谢。如果您将您的评论作为答案,那么我可以接受!
  • "为什么必须将图像存储在 images.xcassets 中?"因为 .xcassets 受益于应用程序精简,而捆绑解决方案则没有。

标签: xcode swift ios8 uiimage xcasset


【解决方案1】:

如果您需要使用 pathForResource() 来避免图像缓存,则无法使用 images.xcassets。在这种情况下,您需要在 XCode 中创建组,并在那里添加图像(确保该图像被复制到 Copy Bundle Resources)。之后就写:

斯威夫特 5:

let bundlePath = Bundle.main.path(forResource: "imageName", ofType: "jpg")
let image = UIImage(contentsOfFile: bundlePath!)

老斯威夫特:

let bundlePath = NSBundle.mainBundle().pathForResource("imageName", ofType: "jpg") 
let image = UIImage(contentsOfFile: bundlePath!) 

【讨论】:

  • 在使用此版本之前,应用程序开始时内存较少 (35mb),随着时间的推移会增加(在加载所有图像之前最多 150mb)。现在它立即以 80mb 开始,但保持在原来的水平。对这种行为有什么想法吗?
【解决方案2】:
import Foundation
import UIKit

enum UIImageType: String {
    case PNG = "png"
    case JPG = "jpg"
    case JPEG = "jpeg"
}

extension UIImage {

    convenience init?(contentsOfFile name: String, ofType: UIImageType) {
        guard let bundlePath = Bundle.main.path(forResource: name, ofType: ofType.rawValue) else {
            return nil
        }
        self.init(contentsOfFile: bundlePath)!
    }

}

用途:

let imageView.image = UIImage(contentsOfFile: "Background", ofType: .JPG)

【讨论】:

  • self.init(contentsOfFile: bundlePath)! 解包无效,因为它是一个可失败的初始化程序
【解决方案3】:

当您从图像组资源中实现图像数组时,您可以将每个图像(比如说 b1、b2、b3、b4、b5)加载为

var imageIndex = 0
lazy var imageList = ["b1","b2","b3","b4","b5"]
let imagePath = Bundle.main.path(forResource: imageList[imageIndex], ofType: "jpg")
imageview.image = UIImage(contentsOfFile: imagePath!)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-05
    • 2015-01-08
    • 2012-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多