0

これは drawRect 内にあります。

NSString *generated = [Entry generateString];

const char *cString = (const char*)[generated UTF8String];

dispatch_queue_t queue = dispatch_queue_create(cString, NULL);*/

dispatch_async(queue, ^{

    Media *media = [self.entry.media objectAtIndex:i];

    UIImage *image = [media getThumbnail];

    dispatch_async(dispatch_get_main_queue(), ^{

        int bottom = [JHomeViewCell yOfMessageBottomWithMessageHeight:self.cellInfo.messageHeight
                                                            withMonth:self.cellInfo.hasMonth];

        CGRect frame = CGRectMake(87 + (68 * i),
                                  bottom,
                                  THUMBNAIL_SIZE.width,
                                  THUMBNAIL_SIZE.height);

        [image drawInRect:frame];
    });

});

現在、objectAtIndex 行でクラッシュしています。無効なインデックスではありません。コードはここ以外では正常に動作します。

編集:このエラーが発生しました:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'statement is still active'

編集 2: 最初に media.count を取得する NSLogs を入れました。同じエラーでクラッシュしました。

4

1 に答える 1

6

ここでの問題は、あるべき場所の外に描画していることです。から戻ったdrawRect:時点で、オペレーティング システムに操作が完了したことが通知されています。戻る前に非同期スレッドを生成することはできずdrawRect:、メイン スレッドに戻るだけで描画できると期待することはできませんdrawRect:。これは、コンテキストから戻ると破棄されるためです。

invalidateRect:これを行う通常の方法は、別のスレッドに情報をキャッシュしてから、描画する必要がある領域を呼び出して、drawRect:メソッドがすばやく描画して終了する以外は何もしないようにすることです。

サムネイルを遅延読み込みする場合は、サムネイルのコピーをプライベートな場所に保存し (おそらく NSCache を使用し、画像 ID をキーとして使用)、drawRect:が呼び出されたときに画像がキャッシュに存在する場合は、描画することをお勧めします。それ以外の場合は、プレースホルダーを描画し、GCD を使用してサムネイル作成用のキューに画像を追加します。そのディスパッチ キュー呼び出しの内部:

  • サムネイルを取得する
  • キャッシュに保存する
  • invalidateRect画像を含む領域を呼び出す

場所を計算するのが難しい場合、またはサムネイルを非常に速く取得している場合は、invalidateRect: を遅らせて、描画ルーチンの最後に最終的な dispatch_async で呼び出すことができます (ただし、サムネイルをキューに入れている場合のみ)検索)。これにより、単一のサムネイルを含む領域ごとに複数の再描画が行われるのではなく、単一の領域全体の再描画が行われます。

于 2012-05-26T12:53:03.567 に答える