iOSはGCD第3編(dispatch_group_enterとdispatch_group_leave)を深く理解している.

1765 ワード

ずっとdispatch_group_enter(group)、dispatch_group_leave(group)はよく知らないので、最近いくつかのブログを見て、権当理解記憶を整理しました.
Calling this function indicates another block has joined the group through
  a means other than dispatch_group_async(). Calls to this function must be
 * balanced with dispatch_group_leave().
 group, dispatch_group_async ;
 dispatch_group_enter()、dispatch_group_leave() ;
void
dispatch_group_enter(dispatch_group_t group);

個人的な理解:メモリ管理の参照カウントと同様にgroupにも整形変数(仮定のみ)があり、enterを呼び出すとカウントが1を加算し、leaveを呼び出すとカウントが1を減算し、カウントが0の場合dispatch_を呼び出すと考えられます.group_notifyかつdispatch_group_waitは待機を停止します.
以上の内容はhttp://www.jianshu.com/p/228403206664作者:liang 1991
コード例:(から)http://www.jianshu.com/p/471469ad9af1老馬の春
- (void)test {
    NSURL *url = [NSURL URLWithString:@"http://upload-images.jianshu.io/upload_images/1432482-dcc38746f56a89ab.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"];

    SDWebImageManager *manager = [SDWebImageManager sharedManager];

    dispatch_group_t group = dispatch_group_create();

    dispatch_group_enter(group);
    [manager loadImageWithURL:url options:SDWebImageRefreshCached progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
        dispatch_group_leave(group);
    }];

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@" ");
    });
}

Enterメソッドとleaveメソッドはペアで表示する必要があります.leaveを呼び出す回数がenterより多いとクラッシュします.SDを使用する場合、OptionsがSDWebImageRefreshCachedに設定されている場合、このcompletionBlockは少なくとも2回呼び出され、まずキャッシュ内のピクチャに戻ります.次にダウンロードが完了した後に再びBlockを呼び出すのがクラッシュの原因です.
上記の方法のクラッシュを再現するには、画像のダウンロードが完了したら、新しい方法を呼び出せばいいです.