调试在保留周期中运行到块

时间:2015-12-18 11:15:11

标签: ios objective-c uiimageview afnetworking block

我有问题,我已经知道不能使用那种方式,但我想在这里问的只是解释,而不是如何修复。请注意。

我正在使用UIImageView+AFNetworking,我正在拨打这样的服务:

UIImageView* imageView = [[UIImageView alloc]init];
    [imageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
        NSLog(@"In here.");
    } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
        completionBlock(nil, error);
    }];

这种情况下,它不会遇到NSLog(@"In here.")。我们可以看到imageView已发布。但是,当我这样使用时:

UIImageView* imageView = [[UIImageView alloc]init];
    [imageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
        NSLog(@"In here.");
        imageView.image = image; /* I know this will make retain cycle. but don't care, just need explanation why? */
    } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
        completionBlock(nil, error);
    }];

现在调试进入NSLog(@"In here.")imageView某些人仍然保留,有人告诉我原因吗?

注意:请不要给出解决方法如何修复和纠正使用方法,请解释原因?

=====

感谢您的支持,我终于明白了。

在第一个代码段中,imageView releasesetImageWithURLRequest success,因此它不会调用NSLog(@"In here.")阻止,这就是为什么{{1}没有被调用。

在第二个中,通过设置imageView.image = image,将使保留周期,这意味着imageView现在正在对success块进行强引用,然后在块内,我&# 39; m要求imageView使用,所以现在success阻止了对imageView的强引用,这使得保留周期和现在imageView不会被释放。因此,进入NSLog(@"In here.")

1 个答案:

答案 0 :(得分:1)

我假设您的代码看起来像这样,并在ARC下运行

- (void) yourMethod {
    UIImageView* imageView = [[UIImageView alloc]init];
    [imageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
        NSLog(@"In here.");
    } failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
        completionBlock(nil, error);
    }];
}

在ARC下,当控件到达imageView的末尾时,yourMethod会被释放。

添加:

imageView.image = image;

success块保留对imageView的引用,这就是为什么您会看到“在此处”消息(imageView将在success结束时取消分配的原因阻止执行)。尝试将imageView声明为您班级的强大属性,并且您应该“在此处”而不将此行添加到success块。