2

テストではクラッシュは発生しませんでしたが、iTunesConnect から次のようなクラッシュ レポートをいくつか受け取りました。

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x45d319f8
Crashed Thread:  0

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   libobjc.A.dylib                 0x3a6595be objc_msgSend + 30
1   UIKit                           0x34796e30 -[UIImageView setImage:] + 116
2   My App                      0x000c40b2 -[AsyncImageView setImage:] (AsyncImageView.m:224)
3   My App                      0x000c3950 __47-[AsyncImageView loadImageWithURL:animated:]_block_invoke_2 (AsyncImageView.m:147)

AsyncImageView は、URL から非同期的に画像をロードする典型的な UIImageView サブクラスです。

問題の行番号が示されているアセット読み込みコードは次のとおりです。

- (void)loadImageWithURL:(NSURL *)url animated:(BOOL)animated {

    if (url == nil) {
        [self setImage:nil];
        return;
    }

    self.imageAsset = [[Asset alloc] init];
    self.imageAsset.assetURL = url;

    AssetRequest *request = [[AssetRequest alloc] init];
    request.assetURL = url;

    __weak AsyncImageView *weakSelf = self;
    self.assetLoader = [AssetLoader AssetLoaderWithRequest:request
                                                 completion:^(Asset *asset){
                                                    dispatch_async(dispatch_get_main_queue(), ^{

                                                    if (weakSelf.imageAsset.assetURL == asset.assetURL) {

                                                             weakSelf.imageAsset = asset;

                                                             if (animated) {
                                                                 CATransition *transition = [CATransition animation];
                                                                 transition.type = kCATransitionFade;
                                                                 transition.duration = 0.20;
                                                                 [weakSelf.layer addAnimation:transition forKey:nil];
                                                             }

                                                            [weakSelf setImage:weakSelf.imageAsset.assetImage]; //THIS IS LINE 147


                                                             [weakSelf setDisplayLoadingIndicator:NO];
                                                             [weakSelf stopAnimating];
                                                    }

                                                    });
                                                 }
                                                     error:^(NSError *err){

                                                         if (weakSelf.failedToLoad)
                                                             weakSelf.failedToLoad(url);

                                                     }];

    [self.assetLoader load];
}

そして、問題の行番号が示されている画像を設定する場所は次のとおりです。

- (void)setImage:(UIImage *)image {

        if (image) {
            [super setImage:image]; //THIS IS LINE 224
            [self hidePlaceholderView];

            if (self.imageLoadedBlock)
                self.imageLoadedBlock();
        }
        else {
            [self showPlaceholderView];
        }

    }

クラッシュ レポートは、イメージの設定時にクラッシュが発生したことを示しています。これが発生する明らかな理由はありますか?または、さらにエラーチェックを行うことができますか (画像が null ではないことを既に確認しています)? 繰り返しますが、これは常に発生するわけではなく、たまにしか発生しません。

4

2 に答える 2

0

SDWebImage のソース コードを調べたところ、アセット ローダーが完了すると次のようになります。

if (!weakSelf) {
   return;
}

dispatch_async(dispatch_get_main_queue(), ^{
   if (weakSelf.imageAsset.assetURL == asset.assetURL) {
      weakSelf.imageAsset = asset;
      [weakSelf setImage:weakSelf.imageAsset.assetImage];
       ...
    }                                                         
 });

したがって、基本的にweakSelfが存在しなくなった場合は何もしません。それがまだ存在するかどうかを自問するのは少し奇妙に思えますが、これで問題は解決しますか?

于 2013-09-10T17:41:43.817 に答える