Capturing 'self' strongly in this block is likely to lead to a retain cycle [duplicate]
2016-01-06 14:28
751 查看
转载至: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: capturing self strongly in this block is likely to lead to a retain cycle 5 answers 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 selfstrongly 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 selfcaused 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 selfwithin 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 _someStringinstance variable carries an implicit reference to self, and is actually equivalent to: self.block = ^{ NSLog(@"%@", self->_someString); }; One might be inclined to just use weakSelfpattern again, resulting in the weakSelf->_someStringsyntax, but the compiler will warn you about this: Dereferencing a __weakpointer is not allowed due to possible null value caused by race condition, assign it to strongvariable first You therefore resolve this by using the weakSelfpattern, but also create a local strongvariable 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 strongreference, 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 selfbeing deallocated while the block is executing, resulting in unintended consequences. This weakSelf/ strongSelfpattern 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.generalInstaImagein 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. |
相关文章推荐
- 行为树-学习笔记(4)-rain插件AI巡逻实现
- JetBrain WebStorm 注册码
- 反射给对象赋值遇到的问题——类型转换[转http://blog.csdn.net/xiaohan2826/article/details/8536074]
- DaisyDisk----Mac文件目录管理神器
- ideaIU-15.0.2 注册码
- ideaic快捷键
- ideaic快捷键
- cin输入错误时导致failbit为1时的缓冲区分析。
- 2016深度学习统治人工智能?深度学习十大框架
- 导航<nav>,视频<video>
- Rails安装指定版本,删除指定版本,rvm卸载
- RAID详解[RAID0/RAID1/RAID10/RAID5]
- 怎么解决Failed to load the JNIshared library
- AIX下生成zip文件
- 【CodeForces 605A】BUPT 2015 newbie practice #2 div2-E - Sorting Railway Cars
- [知其然不知其所以然-16] page reclaim and hibernation failure
- Installation error: INSTALL_FAILED_UPDATE_INCOMPATIBLE Please check logcat output for more details.
- Daily Scrum – 1/5
- Managing Data in Containers
- 函数不能嵌套定义http://blog.csdn.net/douyuhua0918/article/details/7452915