3

テーブルビューの行ごとに画像をダウンロードしたいので、ブロックを使ってこれを行う方法を書きました。

indexPath と tableView は、If ステートメントで使用されているため、完了ブロックによってコピーされない可能性があると思いました。したがって、完了ブロックが実行される前にそれらを保持します。

コードは次のとおりです。

- (void)downloadImageAtURL:(NSString *)imageURL name:(NSString *)name serial:(BOOL)serial forTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath
{
    NSMutableDictionary *cachedImagesOfURLs = self.cachedImagesOfURLs;

    UITableView *strongTableView = [tableView retain];
    NSIndexPath *strongIndexPath = [indexPath retain];

    [self.downloadManager downloadImageAtURL:imageURL
                                  identifier:[self identifierForIndexPath:indexPath]
                                      serial:serial
                                  completion:^(UIImage *image) {
                                      if (image) {
                                          [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                              [cachedImagesOfURLs setObject:image forKey:imageURL];

                                              id cell = [strongTableView cellForRowAtIndexPath:strongIndexPath];
                                              if ([cell respondsToSelector:@selector(didDownloadImage:withName:)]) {
                                                  [cell didDownloadImage:image withName:name];
                                              }
                                          }];
                                      }

                                      [strongTableView release];
                                      [strongIndexPath release];
                                  }];
}

しかし、その結果、完了ブロックが実行され、ブロックを作成してメインスレッドで実行しようとすると、クラッシュします。デバッガーは「-[XXX cellForRowAtIndexPath:]: unrecognized selector sent to instance」を出力します。tableView と indexPath の割り当てが解除されているようです。

しかし、理由はわかりません。私はそれらを保持しようとしました。このクラッシュの発生を防ぐ方法を誰か教えてもらえますか? どうもありがとうございます!

4

2 に答える 2

1

これで十分だと思います

- (void)downloadImageAtURL:(NSString *)imageURL name:(NSString *)name serial:(BOOL)serial forTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath
{
    NSMutableDictionary *cachedImagesOfURLs = self.cachedImagesOfURLs;

    [self.downloadManager downloadImageAtURL:imageURL
                                  identifier:[self identifierForIndexPath:indexPath]
                                      serial:serial
                                  completion:^(UIImage *image) {
                                      if (image) {
                                              [cachedImagesOfURLs setObject:image forKey:imageURL];

                                              id cell = [tableView cellForRowAtIndexPath:indexPath];
                                              if ([cell respondsToSelector:@selector(didDownloadImage:withName:)]) {
                                                  [cell didDownloadImage:image withName:name];
                                              }
                                      }
                                  }];
}
于 2013-03-14T04:26:55.510 に答える
0

さらに少ないコード。あなたが参照しているコードのビットがどのように機能するかはわかりませんが、名前から、次で十分だと思います:

- (void)downloadImageAtURL:(NSString *)imageURL name:(NSString *)name serial:(BOOL)serial forTableView:(UITableView *)tableView indexPath:(NSIndexPath *)indexPath {

    NSMutableDictionary *cachedImagesOfURLs = self.cachedImagesOfURLs;

    [self.downloadManager downloadImageAtURL:imageURL identifier:[self identifierForIndexPath:indexPath] serial:serial completion:^(UIImage *image) {
        if (image) {
            [cachedImagesOfURLs setObject:image forKey:imageURL];
            id cell = [strongTableView cellForRowAtIndexPath:strongIndexPath];
            if ([cell respondsToSelector:@selector(didDownloadImage:withName:)]) {
                [cell didDownloadImage:image withName:name];
            }
        }
    }];
}
于 2013-03-14T04:31:26.977 に答える