ios-block循环引用简析
来源:互联网 发布:用c语言画太极图 编辑:程序博客网 时间:2024/05/21 09:30
**首先明白一点, 由于Block是默认建立在栈上, 所以如果离开方法作用域, Block就会被丢弃,
在非ARC情况下, 我们要返回一个Block ,需要 [Block copy];
在ARC下, 以下几种情况, Block会自动被从栈复制到堆:
1.被执行copy方法
2.作为方法返回值
3.将Block赋值给附有__strong修饰符的id类型的类或者Blcok类型成员变量时
4.在方法名中含有usingBlock的Cocoa框架方法或者GDC的API中传递的时候.**
下面讲在ARC模式下去除因写法产生的告警时需要注意的问题。
像上面的写法其实在ARC中会产生(Capturing ‘demo’ strongly in this block is likely to lead to a retain cycle)告警。如下图:
在ARC中,编译器智能化了,直接提示这样写会产生循环引用。因此很多爱去除告警的朋友就会想法去掉,好,咱再来看去掉时需注意的问题。
情况一:
[objc]view plaincopy
- (IBAction)onTest:(id)sender
{
__weakBlockDemo*demo = [[BlockDemoalloc]init];
[demosetExecuteFinished:^{
if(demo.resultCode==200) {
NSLog(@”call back ok.”);
}
}];
[demoexecuteTest];
}
直接在前面加一个__weak,但这样真的没有告警了吗?如果有,哪么恭喜欢你,说明编译器还帮你大忙。见下图
这时还会告警,说这是一个WEAK变量,就马上会被release。因此就不会执行block中的内容。大家可以运行一下看
输出结果为:
[cpp]view plaincopy
2014-07-24 19:38:02.453 blockDemo[25305:60b] Object Constructor!
2014-07-24 19:38:02.454 blockDemo[25305:60b] Object Destoryed!
很显然,马上被release了,所以block 中的代码根本就不执行。
谢天谢地,幸好编译器提前告诉了我们有这个隐性危险。相信大家为解决告警,又会得到一个比较圆满的解决方案,见下:
[objc]view plaincopy
- (IBAction)onTest:(id)sender
{
BlockDemo*demo = [[BlockDemoalloc]init];
__weak typeof(BlockDemo) *weakDemo = demo;
[demosetExecuteFinished:^{
if(weakDemo.resultCode==200) {
NSLog(@”call back ok.”);
}
}];
[demoexecuteTest];
}
这样写,即去除了告警又保证了block的运行。这才是我们最终想要的结果。
输出为:
[cpp]view plaincopy
2014-07-24 19:40:33.204 blockDemo[25328:60b] Object Constructor!
2014-07-24 19:40:38.206 blockDemo[25328:60b] call back ok.
2014-07-24 19:40:38.207 blockDemo[25328:60b] Object Destoryed!
但大家别得意。有提示,相信大家都能处理,并得到个好的解决方法。哪么下面大来再来看一下这个写法,让你真心甘拜下风。。。。。
[objc]view plaincopy
- (IBAction)onTest:(id)sender
{
__weakBlockDemo*demo = [BlockDemoblockdemo];//这里才是重点,前面是[[BlockDemo alloc]init];会有告警。
[demosetExecuteFinished:^{
if(demo.resultCode==200) {
NSLog(@”call back ok.”);
}
}];
[demoexecuteTest];
}
其实只是把init放到了类方法中进行书写而已,但会有什么不同。
[objc]view plaincopy
- (BlockDemo*)blockdemo
{
returnOBJC_AUTORELEASE([[BlockDemoalloc]init]);
}
不同点见下图:真心看不到作何告警,是不是。但这存在什么风险,风险就是运行的时候,block根本就没有run。因为对象早就释放了。
直接输出:
[cpp]view plaincopy
2014-07-24 19:47:53.033 blockDemo[25395:60b] Object Constructor!
2014-07-24 19:47:53.035 blockDemo[25395:60b] Object Destoryed!
因此,写这个主要用来告戒一些喜欢用BLOCK但又想当然的朋友,有一些朋友喜欢去除告警,但只是盲目的加上__weak 或__block关键语,往往可能存在一些重大的安全隐患。就像演示中block根本不走。如果到了发布时,为了去告警而这样简单的处理了,并没有进行测试就打包。哪么将死得很惨。。。。。
好,到了尾声,来说说为什么朋友问我block会不会引行死循环,我说不会的理由。
见码:
[objc]view plaincopy
- (IBAction)onTest:(id)sender
{
BlockDemo*demo = [BlockDemoblockdemo];//[[BlockDemo alloc]init];
[demosetExecuteFinishedParam:^(BlockDemo* ademo) {
if(ademo.resultCode==200) {
NSLog(@”call back ok.”);
}
}];
[demoexecuteTest];
}
不管是在外面init,还是在里面,且没有加__block 及__weak。为什么,因为我个人常常在使用自己写的block时,如果是回调,比较喜欢把自身当作参数传到block中。这样期实是编译器给我们做了弱引用。因此不会产生循环引用。
转自:http://blog.csdn.net/fengsh998/article/details/38090205
- ios-block循环引用简析
- ios block循环引用问题
- ios block循环引用问题
- ios block循环引用问题
- ios block循环引用问题
- ios- block循环引用问题
- ios- block循环引用问题
- iOS block循环引用问题
- iOS Block循环引用检测
- iOS block之循环引用
- ios block 去循环引用 __weak
- ios Block解决循环引用和回传值
- ios中block的循环引用
- iOS开发--Block容易造成循环引用
- iOS Block循环引用精讲
- iOS Block的循环引用问题
- iOS Block循环引用精讲
- iOS Block循环引用精讲
- ssh比较实际的一个学习顺序
- 简单的正则表达式匹配
- 从4行代码看右值引用
- 一个顶N个的NextResult
- 剑指offer:跳台阶(循环和递归)
- ios-block循环引用简析
- [Objective-C] Objective-C中的id
- 设计模式之Bridge模式(笔记)
- cmd命令重定向输出
- Java流与文件
- Windows.h和Winsock2.h冲突问题
- lua学习--记录(2)
- 125.按规定删除字符
- 让我们一起Go(二)