2

I am trying to use UIImageView extension of AFNetworking2.6.3 to get images from a remote server. everything works fine, images have returned and rendered successfully. but I get a retain cycle warning in Xcode7.3.1: Capturing 'cell' strongly in this block is likely to lead to a retain cycle

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if(self.dataSourceModel) {
        Model *model = self.dataSourceModel.items[indexPath.row];
        NSURL *url = [NSURL URLWithString:model.imageURL];
        NSURLRequest *theRequest = [NSURLRequest requestWithURL:url];
        UIImage *placeholderImage = [UIImage imageNamed:@"placeholder"];

        //I don't use __weak cell in the block
        [cell.imageView setImageWithURLRequest:theRequest placeholderImage:placeholderImage success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
            cell.imageView.image = image; //get warning at this line
            [cell setNeedsLayout];
        } failure:nil];
    }
    return cell;
}

I can see since the cell instance has been captured in the block, so the block has the ownership of the cell instance(and cell.imageView as well). if the retain cycle really exists, the cell or imageView should have the ownership of the block.

but I have reviewed the UIImageView+AFNetworking.h and UIImageView+AFNetworking.m source code, the UIImageView doesn't have any property of blocks. the block is just a parameter of the method, not a instance variable. UITableViewCell doesn't have the ownership of the blocks either.

I even used Leaks to check, and Leaks didn't report any error.

So I believe there is no retain cycle here, but why I still get the Xcode warning here ?? If I use __weak cell__weak UITableViewCell *weakCell = cell;, the warning will go away. But I still wanna know:

  • does it have a retain cycle here?
  • do I really need to use __weak cell?
  • or maybe imageView or cell really has the ownership of the block which I didn't realize?

Any hints will help, thanks a lot.

Lyn
  • 29
  • 2

1 Answers1

1

There's certainly no retain cycle, and you can avoid the warning by omitting the code in the completion block. Taking a look at the AFNetworking imageView subclass (line 152), the culminating point of setImage... is to set the image view's image. There's need for your code to set it again, or to change the layout state.

There should also be no need for if (self.dataSourceModel). If the datasource is built right, we've answered the number of rows in tableView:numberOfRowsInSection:, and that answer is zero when the model is empty, avoiding the call to cellForRow... altogether.

danh
  • 62,181
  • 10
  • 95
  • 136
  • thx for ur reply. Now I see it's not retain cycle. But I don't understand your meaning of **omitting the code in the completion block.** Do you mean sending a nil success block or an empty success block? I look at AFNetworking imageView subclass (line 152).Only if the success is nil, then AFNetworking will setImage for me. So if My understanding is correct, I think i still need to call setImage and setNeedsLayout in the success block manually. – Lyn May 31 '16 at 16:28
  • Could you give me the code example how to use the mehod `[cell.imageView setImageWithURLRequest: placeholderImage success:failure:];` to get images without Xcode warning? – Lyn May 31 '16 at 16:28
  • @Lyn, I think the method should work fine with a nil completion block. (notice `if (success)` on line 149 of the UIImageView+AFNetworking.m. Does that not produce images in the image view? If not, implement the failure block to see if you can get a hint about what's going wrong. – danh May 31 '16 at 16:47
  • I have tried to use nil success block. images can be fetched from remote as expected, but can't be rendered into tableView. I still need to call setNeedsLayout in the completion block for rendering. @danh, thx for your help again :) – Lyn Jun 01 '16 at 03:59
  • Is there a doc that says you must. That sounds wrong. Anyway, regarding your question, there's no retain cycle either way. – danh Jun 01 '16 at 04:03