Capturing 'self' strongly in this block is likely to lead to a retain cycle [duplicate]

转载至:http://stackoverflow.com/questions/17009966/capturing-self-strongly-in-this-block-is-likely-to-lead-to-a-retain-cycle

问题描述:


13down votefavorite

8

This question already has an answer here:

I have reqest with block. But the compiler issues a warning

"Capturing ‘self‘ strongly in this block is likely to lead to a retain cycle"

__weak typeof(self) weakSelf = self;
[generalInstaImage setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:data[@"images"][@"low_resolution"][@"url"]]] placeholderImage:[UIImage imageNamed:@"Default"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
    NSLog(@"success");
    [generalInstaImage setImage: image];
    [weakSelf saveImage:generalInstaImage.image withName:data[@"id"]];

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
        NSLog(@"fail");
}];

I try example write like weakSelf.generalInstaImage, but then the compiler generates an error and do not compile.

解决方法:


up vote44down voteaccepted

When you receive this warning:

Capturing self strongly in this block is likely to lead to a retain cycle

You should review your block for:
(a) any explicit references to self
(b) any implicit references to self caused by referencing any instance variables.

Let‘s imagine that we have some simple class property that was a block (this will experience the same "retain cycle" warnings as your question, but will keep my examples a little simpler):

@property (nonatomic, copy) void (^block)(void);

And let‘s assume we had some other class property we wanted to use inside our block:

@property (nonatomic, strong) NSString *someString;

If you reference self within the block (in my example below, in process of accessing this property), you will obviously receive that warning about the retain cycle risk:

self.block = ^{
    NSLog(@"%@", self.someString);
};

That is remedied via the pattern you suggested, namely:

__weak typeof(self) weakSelf = self;

self.block = ^{
    NSLog(@"%@", weakSelf.someString);
};

Less obvious, you will also receive the "retain cycle" warning if you reference an instance variable of the class inside the block, for example:

self.block = ^{
    NSLog(@"%@", _someString);
};

This is because the _someString instance variable carries an implicit reference to self, and is actually equivalent to:

self.block = ^{
    NSLog(@"%@", self->_someString);
};

One might be inclined to just use weakSelf pattern again, resulting in the weakSelf->_someStringsyntax, but the compiler will warn you about this:

Dereferencing a __weak pointer is not allowed due to possible null value caused by race condition, assign it to strong variable first

You therefore resolve this by using the weakSelf pattern, but also create a local strong variable within the block and use that to dereference the instance variable:

__weak typeof(self) weakSelf = self;

self.block = ^{
    __strong typeof(self) strongSelf = weakSelf;

    if (strongSelf) {
        NSLog(@"%@", strongSelf->_someString);

        // or better, just use the property
        //
        // NSLog(@"%@", strongSelf.someString);
    }
};

As an aside, this creation of a local strong reference, strongSelf, inside the block has other advantages, too, namely that if the completion block is running asynchronously on a different thread, you don‘t have to worry about self being deallocated while the block is executing, resulting in unintended consequences.

This weakSelf/strongSelf pattern is very useful when dealing with block properties and you want to prevent retain cycles (aka strong reference cycles), but at the same time ensuring that selfcannot be deallocated in the middle of the execution of the completion block.

FYI, Apple discusses this pattern in the "non-trivial cycles" discussion further down in the Use Lifetime Qualifiers to Avoid Strong Reference Cycles section of the Transitioning to ARC Release Notes.



You report that you received some "error" when you referenced weakSelf.generalInstaImage in your example. This is the correct way to resolve this "retain cycle" warning, so if you received some warning, you should share that with us, as well as show us how you declared the property.

Capturing 'self' strongly in this block is likely to lead to a retain cycle [duplicate]

时间: 2024-12-15 10:23:13

Capturing 'self' strongly in this block is likely to lead to a retain cycle [duplicate]的相关文章

决绝Capturing 'demo' strongly in this block is likely to lead to a retain cycle

- (IBAction)onTest:(id)sender { BlockDemo *demo = [[BlockDemo alloc]init];  __weak typeof(BlockDemo) *weakDemo = demo;  [demo setExecuteFinished:^{ if (weakDemo.resultCode == 200) { NSLog(@"call back ok."); } }]; [demo executeTest]; } 决绝Capturin

在block函数中规避错误信息 "capturing self strongly in this block is likely to lead to a retain cycle”

以形如 _fontValueChangedBlock = ^(){ [self.fontSmallButton addTarget:self action:@selector(btnFontSmallClicked) forControlEvents:UIControlEventTouchUpInside]; }; 的代码为例,这个代码运行会报警告."capturing self strongly in this block is likely to lead to a retain cycle

capturing self strongly in this block is likely to lead to a retain cycle

一个使用Block语法的实例变量,在引用另一个实例变量的时候,经常会引起retain cycle. _items = [[NSMutableArray alloc] init]; _block = ^{ [_items addObject:@"Hello!"]; //_block引用了_items,导致retain cycle. }; 写成下面格式 __block ViewController *blockSelf = self; _block = ^{ [blockSelf->

IOS中的block 循环引用和retain cycle (经典)

retain cycle 的产生 说到retain cycle,首先要提一下Objective-C的内存管理机制. 作为C语言的超集,Objective-C延续了C语言中手动管理内存的方式,但是区别于C++的极其非人道的内存管理,Objective-C提出了一些机制来减少内存管理的难度. 比如:内存计数. 在Objective-C中,凡是继承自NSObject的类都提供了两种方法,retain和release.当我们调用一个对象的retain时,这个对象的内存计数加1,反之,当我们调用relea

【少年,放松~】出现block循环引用的三种情况和处理办法

刚入职在看已经上线的项目,其中用到block进行快捷回调的做法很常用,但是Xcode都给给以了如下[循环引用]的警告(如下)的情况,结合网络上的查找和自己的理解,进行总结如下. // Capturing 'self' strongly in this block is likely to lead to a retain cycle 出现这种情况的原因主要是:因为block的特性,声明block的对象都会以copy的形式持有block,而block对于它内部的对象也会进行强引用,从而导致了循环引

iOS 8:【转】Block循环引用

源地址:http://fann.im/blog/2013/04/17/retain-cycle-in-blocks/ 个人笔记,可能会有理解不够透彻而错误. @fannheyward Objective-C 是基于引用计数(retainCount)来做内存管理,ClassA 用到 ClassB 的时候,通过 alloc/retain/copy 等将 objectB.retainCount+1,不需要的时候通过 release/autorelease 将 objectB.retainCount-1

写给喜欢用Block的朋友(ios Block)

作者:fengsh998 原文地址:http://blog.csdn.net/fengsh998/article/details/38090205 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号fengsh998来支持我,谢谢! 本文不讲block如何声明及使用,只讲block在使用过程中暂时遇到及带来的隐性危险. 主要基于两点进行演示: 1.block 的循环引用(retain cycle) 2.去除block产生的告警时,需注意问题. 有一次,朋友问我当一个对象中的b

iOS开发——Block引起循环引用的解决方案

内存问题始终是软件开发中的头等大事,iOS开发中也不例外,在面试中也是必问的问题.今天我们主要来讲讲Block中涉及的循环引用问题.当我们自己一开始写代码的时候,可能会大量在block中使用self,但是当看到别人优秀的代码的时候,发现别人常常不是用self,而使用weakSelf. 为什么呢?本文的示例代码上传至 https://github.com/chenyufeng1991/Block_WeakSelf . 首先我先来说说内存管理的原则: 1.默认使用strong,可选weak.stro

block没那么难(三):block和对象的内存管理

本系列博文总结自<Pro Multithreading and Memory Management for iOS and OS X with ARC> 在上一篇文章中,我们讲了很多关于 block 和基础变量的内存管理,接着我们聊聊 block 和对象的内存管理,如 block 经常会碰到的循环引用问题等等. 获取对象 照例先来段代码轻松下,瞧瞧 block 是怎么获取外部对象的 /********************** capturing objects **************