iOS XCode : capturing [Object/pointer] strongly in this block is likely to lead to a retain cycle

Yup, mungkin bagi beberapa programmer iOS masi bingung soal ARC. Saya menulis ini buat mendokumentasikan error handle yang saya temukan selama ngoding, mengingat jarang sekali tutorial iOS berbahasa Indonesia, dan biar gak lupa kalo nanti nemu masalah seperti ini lagi.

Dan masalahnya adalah (to the point banget) :


- (UIImageView *)addImgProdsAsTabIndex:(NSInteger)index stringURL:(NSString*)URL{
    UIImageView * imgView = [[UIImageView alloc] init];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URL]];
    [request addValue:@"image/*" forHTTPHeaderField:@"Accept"];
    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    spinner.frame = CGRectMake(widthImgProduct * 0.5 - (37 * 0.5), CGRectGetHeight(_scrollProduct.bounds) * 0.5 + 50, 37, 37);
    spinner.tag = 12;
    [imgView addSubview:spinner];
    [spinner startAnimating];
    [imgView setImageWithURLRequest:request placeholderImage:[UIImage imageNamed:@"img_placeholder_product"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
        [spinner setHidden:YES];
        [spinner stopAnimating];
        if (image != nil) {
            //Disini masalahnya
            imgView.image = image;
        }
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
        [spinner setHidden:YES];
        [spinner stopAnimating];
    }];
    imgView.frame = CGRectMake(_marginImgProduct+(index * ((2 * _marginImgProduct) + widthImgProduct)), 0, widthImgProduct, CGRectGetHeight(_scrollProduct.bounds));
    imgView.tag = index;
    [_scrollProduct addSubview:imgView];
    return imgView;
}

Disini di temukan warning capturing imgView strongly in this block is likely to lead to a retain cycle.
yang jadi masalah, dalam blok tersebut tidak bisa menggunakan strong. Sedangkan secara default, imgView itu strong. Kalau kita ubah menjadi weak dengan ditambahkan kode __weak sebelum kode UIImageView, maka imgView gak ada yang hold, sehingga muncul warning assigning retained object to weak variable object will be released after assignment. 
Jadi cara saya untuk handle masalah seperti ini adalah dengan cara seperti berikut:
  1. Buat holder dengan tipe UIImageView untuk menghandle imgView sebagai weak
  2. gunakan holder tersebut untuk menjalankan methodnya dari block
holder : 
__weak typeof(UIImageView) *weakSelf = imgView;

penggunaan :
weakSelf.image = image;

Koding akhir :
- (UIImageView *)addImgProdsAsTabIndex:(NSInteger)index stringURL:(NSString*)URL{
    UIImageView * imgView = [[UIImageView alloc] init];
    __weak typeof(UIImageView) *weakSelf = imgView;
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URL]];
    [request addValue:@"image/*" forHTTPHeaderField:@"Accept"];
    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    spinner.frame = CGRectMake(widthImgProduct * 0.5 - (37 * 0.5), CGRectGetHeight(_scrollProduct.bounds) * 0.5 + 50, 37, 37);
    spinner.tag = 12;
    [imgView addSubview:spinner];
    [spinner startAnimating];
    [imgView setImageWithURLRequest:request placeholderImage:[UIImage imageNamed:@"img_placeholder_product"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
        [spinner setHidden:YES];
        [spinner stopAnimating];
        if (image != nil) {
            weakSelf.image = image;
        }
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
        [spinner setHidden:YES];
        [spinner stopAnimating];
    }];
    imgView.frame = CGRectMake(_marginImgProduct+(index * ((2 * _marginImgProduct) + widthImgProduct)), 0, widthImgProduct, CGRectGetHeight(_scrollProduct.bounds));
    imgView.tag = index;
    [_scrollProduct addSubview:imgView];
    return imgView;
}


Popular posts from this blog

PNScanner - Privacy Policy

Center Scrollview Swift iOS