Ios 调试运行到带有保留周期的块中
我有一个问题,我已经知道不能用那种方式,但我想问的只是解释,而不是如何修复。请注意 我使用的是Ios 调试运行到带有保留周期的块中,ios,objective-c,uiimageview,afnetworking,block,Ios,Objective C,Uiimageview,Afnetworking,Block,我有一个问题,我已经知道不能用那种方式,但我想问的只是解释,而不是如何修复。请注意 我使用的是UIImageView+AFNetworking,我调用的服务如下: UIImageView* imageView = [[UIImageView alloc]init]; [imageView setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest * _Nonnull request, NSHTTP
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);
}];
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(@“在这里”)
。我们可以看到imageView
发布了。但当我这样使用时:
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);
}];
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(@“在这里”)
,imageView
someshow仍然保留,请有人告诉我为什么
注意:请不要给出如何修复和正确使用方法的解决方案,请解释原因
=====
谢谢你的支持,我终于明白了
在第一段代码中,imageView
将在setImageWithURLRequest
的末尾release
,因此它不会调用success
块,这就是为什么不调用NSLog(@“在这里”)
在第二个例子中,通过设置
imageView.image=image
,将使retain循环,这意味着imageView
现在对success
块有一个很强的引用,然后在块内,我调用imageView
使用,因此,现在success
块包含对imageView
的强引用,这使得retain循环,现在imageView
将不会被释放。因此,进入NSLog(@“在这里”)
我假设您的代码看起来像这样,并在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
块的情况下进入“此处”。您的问题不太清楚。“现在调试在这里运行,请有人告诉我为什么?”你的意思是“为什么调试程序会进入“在这里”NSLog()。