1

PHAsset からサムネイルやその他の情報を取得しようとしています。簡略化されたコード スニペットを次に示します。

カメラロールから取得したすべての画像に対して、次のようにします。

static func fetchAsset(asset: PHAsset)
{
        if(asset.mediaType == PHAssetMediaType.Image){
            let screenScale: CGFloat = UIScreen.mainScreen().scale
            let imageSize = CGSize(width: 100 * screenScale, height: 100 * screenScale)

            let options: PHImageRequestOptions = PHImageRequestOptions()
            options.deliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat
            options.resizeMode = PHImageRequestOptionsResizeMode.Fast
            options.synchronous = false

            PHImageManager.defaultManager().requestImageForAsset(asset,
                targetSize: imageSize,
                contentMode: PHImageContentMode.AspectFill,
                options: options,
                resultHandler: { (result, info) -> Void in
                    if (result != nil && result!.scale == screenScale) {

                        var newItemImage = MyImage(isLocal:true)
                        if let fname = asset.valueForKey("filename") as? String{
                            newItemImage.fileName = fname
                        }
                        newItemImage.thumbnail = result
                        asset.requestContentEditingInputWithOptions(PHContentEditingInputRequestOptions()) { (contentEditingInput, info) -> Void in

                            //Get full image
                            let url = contentEditingInput!.fullSizeImageURL

                            newItemImage.url = url
                        }
                        //DO SOMWTHING WITH IMAGE
                    }else
                    {
                        //DO SOMWTHING ELSE
                    }
            })
        }
    }

この段階で 2 つの問題があります。

  1. 最も重要なものですが、それは結果的なものだと思います。処理能力とディスクからの読み取りが多すぎます。エミュレータでは問題なく動作します。しかし、300 ~ 500 枚の画像があるテスト デバイス (iPhone 5、4S) で実行すると、すべての画像を取得している間に 1 ~ 2 分間フリーズします。コレクション全体を1つずつ読み取り、サイズを変更して、このすべての情報をフェッチすると思います。もっと簡単な方法はありますか?ALAsset で可能だったように、サムネイルを直接取得するだけで、すばやく飛んでいました。
  2. 何らかの理由で2回仕事をします。最初に、私が求めていたもの、小さなサムネイル〜60 * 40またはその前後が表示されます。それが私に与えられたら、数秒後に別のループに進み、960 * 640 などの高解像度の画像の取得を開始し、そこでフリーズが発生します。なぜこれが起こっているのかわかりませんが、そうです。

これら 2 つの問題に関する情報は、高く評価されます。

4

2 に答える 2

2

何らかの理由で2回仕事をします

それが本来の役割だからです。お気づきのように、フォト ライブラリから画像を取得するには時間がかかります。したがって、デフォルトの動作では、表示するものがあるように、低解像度の画像をできるだけ早く提供します。その後、より高品質の画像を使用して、場合によっては数回、再度呼び出します。さらに、フェッチは非同期で形成されています。したがって、一度に複数のフェッチ要求が発生する可能性は完全にあり、これにより、コードが自分の足でつまずき始める可能性があります。

それが気に入らない場合は、フェッチ オプションsynchronoustrue— に設定しますが、この呼び出し全体をバックグラウンド キューで行う必要があります。これをシリアルキューで行うことにより、呼び出しが順番に個別に実行され、各画像が 1 回だけ配信されるようにすることができます。さらに、その時(そしてその時だけ)あなたPHImageRequestOptions.DeliveryModeFastFormatは従います。受け取った画像を処理する前に、メイン スレッドに戻ることを忘れないでください。

于 2015-09-21T02:45:13.990 に答える