【问题标题】:Debug runs into block with retain cycle调试遇到带有保留周期的块
【发布时间】:2015-12-18 11:15:11
【问题描述】:

我有问题,我已经知道不能这样使用,但我想在这里问的只是解释,而不是如何解决。请注意。

我正在使用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 someshow 仍然保留,请有人告诉我为什么?

注意:请不要给出解决方法和正确使用方法,只解释原因?

=====

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

在第一个sn-p代码中,imageViewrelease放在setImageWithURLRequest的末尾,所以它不会调用success块,这就是为什么NSLog(@"In here.")没有被调用。

在第二个中,通过设置imageView.image = image,将保持循环,这意味着imageView现在持有对success块的强引用,然后在块内,我调用imageView使用,所以现在success 块持有对imageView 的强引用,这使得保持循环,现在imageView 将不会被释放。因此,请联系NSLog(@"In here.")

【问题讨论】:

  • 你的问题不太清楚。 “现在调试在这里运行,请有人告诉我为什么?”您的意思是“为什么调试器会到达“In here”NSLog() 行?
  • 是的,确切地说,很容易知道。但是让我编辑它。

标签: ios objective-c uiimageview afnetworking block


【解决方案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 下,当控制到达 yourMethod 的末尾时,imageView 将被释放。

通过添加:

imageView.image = image;

success 块保持对imageView 的引用,这就是为什么您会看到“在此处”消息(imageView 将在success 块执行结束时被释放)。尝试将 imageView 声明为你的类的强属性,你应该得到“在此处”而不将此行添加到 success 块。

【讨论】:

  • 不完全,但根据你的想法,我已经得到了答案,非常感谢。
猜你喜欢
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-22
相关资源
最近更新 更多