0

オンラインでダウンロードされた各セルの画像を表示する uitableview があります。

この呼び出しを非同期にするために、NSBlock 操作を使用します。以前は GCD を使用していましたが、GCD をキャンセルすることはできないため、これを使用することを好みます。その理由は、ビューを離れると、画像がアプリのバックグラウンドでダウンロードされ、前のビューに再び入ると、GCD が再びすべてをキューに入れるため、最終的には画像のスタック全体が存在し、ユーザーは uitableview を見ることはありません。それが、NSBlock 操作を選択する理由です。

ただし、私のブロックはキャンセルされません。これは私が使用するコードです (これは - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { ) の一部です:

// Create an operation without any work to do
    downloadImageOperation = [NSBlockOperation new];

    // Make a weak reference to the operation. This is used to check if the operation
    // has been cancelled from within the block
    __weak NSBlockOperation* operation = downloadImageOperation;


    // Give the operation some work to do
    [downloadImageOperation addExecutionBlock: ^() {
        // Download the image
        NSData *data = [NSData dataWithContentsOfURL:[newsimages objectAtIndex:indexPath.row]];;
        UIImage *image = [[UIImage alloc] initWithData:data];
         NSLog(@"%@",image);
        // Make sure the operation was not cancelled whilst the download was in progress
        if (operation.isCancelled) {
            return;
            NSLog(@"gestopt");
        }
        if (image != nil) {

            NSData* imageData = UIImagePNGRepresentation(image);

            [fileManager createFileAtPath:path contents:imageData attributes:nil];
            cell.imageView.image = image;
            cell.imageView.layer.masksToBounds = YES;
            cell.imageView.layer.cornerRadius = 15.0;

        }

        // Do something with the image
    }];

    // Schedule the download by adding the download operation to the queue
    [queuee addOperation:downloadImageOperation];

このコードを使用してキャンセルしました:

-(void)viewDidDisappear:(BOOL)animated {
[downloadImageOperation cancel];
}

ただし、私の NSLog は、ビューが消えた後でも (そこに nslog を置いた後)、まだブロックがあることを示しています。

 2012-09-12 21:32:31.869 App[1631:1a07] <UIImage: 0x3965b0>
 2012-09-12 21:32:32.508 App[1631:1907] <UIImage: 0x180d40>
 2012-09-12 21:32:32.620 App[1631:707] view dissappear!
 2012-09-12 21:32:33.089 App[1631:3a03] <UIImage: 0x3a4380>
 2012-09-12 21:32:33.329 App[1631:5a03] <UIImage: 0x198720>

注意: ビューには毎回 4 つのセルが表示されるため、ビューを離れても、それらはまだキューにあると思います..

4

1 に答える 1

1

あなたのコードは複数のブロックがキューに入れられていないようです - これは正しいですか? そうでない場合は、操作ではなくキューに「キャンセル」を送信する必要があります。

とにかく、あなたの問題はおそらくこの行です:

NSData *data = [NSData dataWithContentsOfURL:[newsimages objectAtIndex:indexPath.row]];;

そのダウンロードは同期的に行われているため、このメッセージの直後に「キャンセル」を送信すると、キャンセルは長い間表示されません。これが、ほとんどの開発者が非同期 NSURLConnections を使用して同時 NSOperations を使用してダウンロードを行う理由です。そのため、リアルタイムでキャンセル メッセージを取得します。

これが ARC であると仮定すると、dealloc にログを追加して、実際に操作が終了またはキャンセルされ、適切に解放されたことを確認できます。[上記のログはリターン後のものであるため、呼び出されることはありません。また、キャンセルされたらできるだけ早く停止するように、 isCancelled メッセージをもっと散らしてください。]

于 2012-09-12T20:08:28.403 に答える