调试运行到具有保留周期的块
Debug runs into block with retain cycle
我有问题,我已经知道不能那样使用,但我想在这里问的只是解释,而不是如何解决。请注意。
我正在使用 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
会在setImageWithURLRequest
的末尾release
,所以它不会调用success
块,这就是为什么NSLog(@"In here.")
未被调用。
在第二个中,通过设置imageView.image = image
,将进行保留循环,这意味着imageView
现在持有对success
块的强引用,然后在块内部,我正在调用 imageView
来使用,所以现在 success
块持有对 imageView
的强引用,这使得保留循环现在 imageView
不会被释放。因此,进入 NSLog(@"In here.")
.
我假设您的代码看起来像这样并在 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
的引用,这就是为什么您会看到 "In here" 消息(imageView
将在 success
阻止执行)。尝试将 imageView
声明为 class 的强 属性,您应该得到 "In here" 而无需将此行添加到 success
块。
我有问题,我已经知道不能那样使用,但我想在这里问的只是解释,而不是如何解决。请注意。
我正在使用 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
会在setImageWithURLRequest
的末尾release
,所以它不会调用success
块,这就是为什么NSLog(@"In here.")
未被调用。
在第二个中,通过设置imageView.image = image
,将进行保留循环,这意味着imageView
现在持有对success
块的强引用,然后在块内部,我正在调用 imageView
来使用,所以现在 success
块持有对 imageView
的强引用,这使得保留循环现在 imageView
不会被释放。因此,进入 NSLog(@"In here.")
.
我假设您的代码看起来像这样并在 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
的引用,这就是为什么您会看到 "In here" 消息(imageView
将在 success
阻止执行)。尝试将 imageView
声明为 class 的强 属性,您应该得到 "In here" 而无需将此行添加到 success
块。