如何将 UIImage(contentsOfFile:String) 与从 Internet 下载的图像数据一起使用?

Posted

技术标签:

【中文标题】如何将 UIImage(contentsOfFile:String) 与从 Internet 下载的图像数据一起使用?【英文标题】:How can I use UIImage(contentsOfFile:String) with image data downloaded from the internet? 【发布时间】:2015-04-03 10:02:50 【问题描述】:

我有一个应用程序正在从网络服务器加载大量图像数据。数据正在通过以下方式保存到 ipad:

func saveParsedObject(objectToSave:AnyObject,dataCode:Int)
    
        var path:String! = self.convertDataCodeToPath(dataCode)
        println( "saveParsedObject - object::\(objectToSave)")
        if NSKeyedArchiver.archiveRootObject(objectToSave, toFile: path)
        
            println("Success writing parsed object to file!")
        
        else
        
            println("Unable to write parsed object to file!")
        
    

数据稍后打开:

func loadParsedObject(dataCode:Int) -> AnyObject?
    
        var path:String! = self.convertDataCodeToPath(dataCode)
        println( " ****** path = \(path) ****** ")
        var dataFromDisk:AnyObject?
        dataFromDisk = NSKeyedUnarchiver.unarchiveObjectWithFile(path)
        println( " ****** dataFromDisk = \(dataFromDisk) ****** ")
        return dataFromDisk
    

图像数据用这段代码保存:

if let imgURLString = imageURLString
        
            println(" ////// Image is not nil /////// ")
            let imageURL = NSURL(string: imageURLString)
            let imageData = NSData(contentsOfURL: imageURL!)

            //println(imageData)
            if let imgData = imageData
            
                self.productImage = UIImage(data: imageData!)
            
            else
            
                println("Image data = nil")
                //println(productName)
            

        

由于数据不是用UIImage(contentsOfFile:String) 保存的,所以当我稍后执行此操作时,它正在被缓存:

if let isProductImgNil = productModel.productImage?
        
            println(" -- product image is not nil -- ")
// productView is my custom view for my productData which is in my productModel object
                productView.backgroundImage.image = productModel.productImage?
//productView.backgroundImage is a UIImageView
//productModel.productImage is a UIImage
        

我找到了这些链接并尝试使用它们以使图像不被缓存。然而,问题要大得多。我需要下载一个图像,将其保存到 HDD 并使用contentsOfFile 加载它,它接受一个字符串而不是NSData 对象,我不知道如何正确执行此操作,即使这种方法确实有意义。

以下是链接:

(1)Swift + Save and Load Image From DocumentDirectory

(2)SO: basic UIImage memory managment

(3)SO: My error but with local images located in .xcassets

(4)SO: Answers says what I should do and I do, however UImage can not be loaded with NSData with caching disabled

解决方案 1

结果:这是我一开始所做的(在(4)中解释)数据被缓存但没有加载两次,应用程序在一段时间后崩溃(在(3)中解释

代码以上

解决方案 2

结果:数据正在被缓存并再次加载(甚至更糟)。崩溃得更快...

代码

解析时保存数据(使用链接(1)):

if let imgURLString = imageURLString
        
            println(" ////// Image is not nil /////// ")
            let imageURL = NSURL(string: imageURLString)
            let imageData = NSData(contentsOfURL: imageURL!)

            var selectedImage = UIImage(data:imageData!)


            let fileManager = NSFileManager.defaultManager()

            var paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String

            var filePathToWrite = "\(paths)/\(imageURLString.lastPathComponent)"

            var imageData1: NSData = UIImagePNGRepresentation(selectedImage)

            fileManager.createFileAtPath(filePathToWrite, contents: imageData1, attributes: nil)

            var getImagePath = paths.stringByAppendingPathComponent(imageURLString.lastPathComponent)

            finalImagePath = getImagePath

            if (fileManager.fileExistsAtPath(getImagePath))
            
                println(" --------------- ")
                println(" Model - FILE AVAILABLE");
                println(getImagePath)
                println(" --------------- ")
                //Pick Image and Use accordingly
                //var imageis: UIImage = UIImage(contentsOfFile: getImagePath)!

                //let data: NSData = UIImagePNGRepresentation(imageis)

            
            else
            
                println(" Model - FILE NOT AVAILABLE");

            

        

并加载数据:

 let fileManager = NSFileManager.defaultManager()

    if (fileManager.fileExistsAtPath(productModel.finalImagePath!))
    
        println("FILE AVAILABLE");
        productView.backgroundImage.image = UIImage(contentsOfFile:productModel.finalImagePath)!
    
    else
    
        println(" - - - - - ")
        println(productModel.finalImagePath!)
        println("FILE NOT AVAILABLE");

    

注意:

productView.backgroundImage.image = UIImage(contentsOfFile:productModel.finalImagePath)!

这对缓存没有帮助...但会将图像加载到视图中。

欢迎提出任何建议。 我将在一个较小的项目中尝试其他一些东西,因为这可能是一个项目问题。

我也将尝试实现对象池 DP,但不知何故我认为它不会有太大帮助,因为一个类别有 202 种产品并且内存会跃升至大约 250-300 MB。如果我打开其他任何东西,我会收到内存警告。更少的内存峰值和应用程序崩溃。

我也可能会尝试动态加载,因为产品正在加载到 UIScrollView 中,但这将是很多工作,因为我没有太多时间。是的,我知道我应该使用 CoreData,但我没有时间学习它。应用程序必须在大约 40 天内完成(剩下的时间不多),我是 swift 的新手 :)。感谢您的帮助:)。

【问题讨论】:

如果你没有太多时间,你应该使用SDWebImage。它以正确的方式为您完成这一切。 我会研究一下。非常感谢:) 应用将进入应用商店。我读过一些具有某种类型框架的应用程序被拒绝。这个框架是这样的吗?我找到了这个 SO 帖子***.com/questions/25866049/create-own-ios-framework。 不,数百个 App Store 应用使用SDWebImage 如果您愿意,可以在答案部分发表评论。我会接受的。我 99% 确定这就是我想要的 :) 【参考方案1】:

如果您没有太多时间,您应该使用SDWebImage。它以正确的方式为您完成这一切。

【讨论】:

以上是关于如何将 UIImage(contentsOfFile:String) 与从 Internet 下载的图像数据一起使用?的主要内容,如果未能解决你的问题,请参考以下文章

使用 UIImage(contentsOfFile: ) 时获取 EXC_BAD_ACCESS

UIImage返回nil但存在

swift上的UIImage无法检查nil

无法在 tvOS 应用程序中加载 LCR 图像

NSDictionary init(contentsOfFile:) 已被弃用,现在怎么办?

使用 contentsOfFile 方法的 NSDictionary 不在 Swift 中构建