7

アプリの使用中のある時点でメモリ不足が原因でアプリが終了し、問題の原因となっているコードの 1 つのチャンクに問題を切り分けました。

以下にコード チャンクをコピーしますが、最初にそれが何をしているのかを説明します。

説明:

ビデオのリストを反復処理する for ループがあります。動画ごとに、for ループは含まれている scrollview のサイズを増やし、ラベルとボタン (どちらも動画に関連するもの) を描画し、動画のサムネイルを非同期的に取得してボタンの下に配置します。

問題:

サムネイル部分のグラブが問題です。これが非同期で行われるという事実が問題だとは思いません。同期的に試してみましたが、それでも終了が発生します。サムネイルを取得するコード (以下のコードの非同期部分全体) をコメント アウトすると、アプリはクラッシュしません。

コード:

注意: 簡潔にするために、場合によってはコードを置き換えるためにコメントを使用しています。

for (int i = [_videoURLs count]-1; i >= 0 ; i--)
    {
        //increase the scrollview size

        //get background image:
        dispatch_async(screenshotQueue, ^{

            AVURLAsset *as = [[AVURLAsset alloc] initWithURL:currentURL options:nil];
            AVAssetImageGenerator *ima = [[AVAssetImageGenerator alloc] initWithAsset:as];
            ima.appliesPreferredTrackTransform = YES;
            NSError *err = NULL;
            CMTime time = CMTimeMake(1, 24);
            CGImageRef imgRef = [ima copyCGImageAtTime:time actualTime:NULL error:&err];
            UIImage *thumbnail = [[UIImage alloc] initWithCGImage:imgRef];

            dispatch_async(dispatch_get_main_queue(), ^{

                UIImageView *backgroundImage = [[UIImageView alloc]initWithFrame:buttonFrame];
                backgroundImage.image = thumbnail;
                backgroundImage.layer.opacity = 0;
                [self.videoScrollView addSubview:backgroundImage];

                [self.videoScrollView sendSubviewToBack:backgroundImage];

                [UIView animateWithDuration:0.5 delay:0.0 options: UIViewAnimationOptionCurveEaseInOut
                 animations:^{
                     backgroundImage.layer.opacity = 1;
                 }
                 completion:^(BOOL finished){}];

            });

        });

        //add title to the screen caps

        //draw the button

    }

私は Xcode 5 を使用しており、iOS 7 を搭載した新しいデバイスでテストしています。私は独学なので、かなりの悪い習慣を身につけたと確信していますが、明らかな何かを見逃していないことを願っていますもう少し経験のある人が拾うでしょう。

私はかなりの量のグーグルとスタックオーバーフローの検索を試み、診断、ログ、およびメモリプロファイルを調べて問題をさらに特定しようとしましたが、役に立ちませんでした。

どんな助けでも大歓迎です!

編集

エラーを再現する方法:

  1. 動画一覧へ
  2. 動画リストを終了
  3. 1+2 を 4 回または 5 回繰り返すと、クラッシュが発生します

ステップ 2. スーパービューから scrollView 全体を単純に削除し、再描画します。ビデオリストに戻るたびに再描画する必要がないことは理解していますが、特定の理由でこれを行っており、これが問題の原因であるとは思いません (間違っている可能性があります)。

編集2

メモリ プロファイルのイメージを次に示します。 ここに画像の説明を入力

4

2 に答える 2

13

あなたが示すコードには大きなリークがあります。以下を使用して Core Foundation オブジェクトを作成しています。

CGImageRef imgRef = [ima copyCGImageAtTime:time actualTime:NULL error:&err];

まだ対応していませんCFRelease

コードは次のようにする必要があります。

CGImageRef imgRef = [ima copyCGImageAtTime:time actualTime:NULL error:&err];
UIImage *thumbnail = [[UIImage alloc] initWithCGImage:imgRef];
CFRelease(imgRef);
于 2013-11-01T13:33:51.120 に答える
2

さて、私はまともな解決策を見つけました。そもそもなぜこれが問題だったのかはまだ完全にはわかりませんが、いくつかの疑いがあります。

サムネイルを生成するプロセスは、for ループを介してスレッドで繰り返し実行するにはあまりにも集中的だったと思います。私はこの予感を持っていたので、上記のコードを調整することにしました。毎回新しいサムネイルを生成する代わりに、新しく生成されたスクリーンショットを png としてドキュメントのホーム ディレクトリに保存します。次に、そこからこのリソースをロードします。これにより、メモリの問題が解消されました。

これが同様の問題を抱えている人に役立つことを願っています-誰かが追加するものがある場合、またはより良い答えがある場合は、私はすべて耳を傾けます.

于 2013-11-01T13:21:44.147 に答える