0

Web サーバーから大量の画像データを読み込んでいるアプリがあります。データは次の方法で 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 + DocumentDirectory から画像を保存して読み込む

(2) SO: 基本的な UIImage メモリ管理

(3) SO: 私のエラーですが、.xcassets にローカル イメージがあります

(4) SO: Answers は私がすべきことと私がすべきことを示していますが、キャッシングが無効になっている NSData で UImage をロードすることはできません

解決策 1

結果:これは私が最初に行ったことです ((4) で説明) データはキャッシュされていますが、2 回読み込まれず、しばらくするとアプリがクラッシュします ((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 を実装しようとしますが、1 つのカテゴリに 202 個の製品があり、メモリが約 250 ~ 300 MB に跳ね上がるため、あまり役に立たないと思います。他のものを開くと、メモリの警告が表示されます。メモリ スパイクがさらに少なくなり、アプリがクラッシュします。

製品が UIScrollView にロードされているため、動的ロードを試すこともできますが、時間がないため、多くの作業が必要になります。はい、CoreData を使用するべきだったことはわかっていますが、それを学ぶ時間がありませんでした。アプリは約 40 日で完了する必要があり (残り時間はあまりありません)、私は迅速に慣れていません :)。ご協力いただきありがとうございます :)。

4

1 に答える 1

1

時間があまりない場合は、 を使用してくださいSDWebImage。これはすべて、正しい方法で行われます。

于 2015-04-05T22:39:45.030 に答える