ARC下的block导致的循环引用问题解析

ARC下的block导致的循环引用问题解析

更详细细节请参考 http://blog.sina.com.cn/s/blog_8c87ba3b0101m599.html

 

ARC下,copy到堆上的block,会强引用进入到该block中的外部变量.这很容易导致循环引用的问题.

比方说:

一个VC(这里指一个controller)中有一个属性为model.VC强引用了它.

VC --> model

这个model呢,里面有一个copy属性的block,该block赋值如下如下.model.demo = ^{

    ......

};

如果这个......没有传VC进来,还好,不会强引用VC,如果是下面的情况:

model.demo = ^{

    ......

    [test getValue:self];

};

那,直接导致的后果就是,这个model强引用了这个VC.

model --> VC

这就造成了一个循环.即使这个VC被pop掉了,垃圾回收机制也无法释放这个VC了,因为,它检测到了这个VC被model强引用了.

 

 

所以,在ARC下面使用block,无论怎样,你都需要注意这几点:

1.  外部对象进入block,请使用__weak修饰后再进入到block中

2.  不要在block中初始化对象,请在block的外面初始化对象后再进入到block中去

3.  无论该block是不是copy的,请都当做copy的block来处理

4.  传入到堆区block中的对象会被强引用

时间: 2024-10-29 11:36:39

ARC下的block导致的循环引用问题解析的相关文章

ARC下block使用情况

ARC与MRC的block有着一些区别,笔记整理ARC的block,仅仅是自己参考的笔记,详情请参考 http://www.cnbluebox.com/?p=255   在开始之前,请新建一个Model类,写几个如下的属性,用于后面测试block的特性.     Block的类型与内存管理 根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock. NSGlobalBlock:类似函数,位于text段: NSStackBlock:

iOS循环引用问题

今天面试问道了循环引用,所以就看了看,原来只是知道使用了Block容易造成循环引用.今天就来简单的介绍一些循环引用. 先来简单介绍一下什么是循环引用? 循环引用可以简单的理解成:A对象引用了B对象,B对象又引用了A对象.两者相互保持对方的一个引用.导致任何时候计数都不为0,最终两者都无法释放. 产生循环引用的方式: 1.NSTimer 比如说我在一个类中声明了一个NSTimer计时器类.而在NSTimer 的方法 + (NSTimer *)scheduledTimerWithTimeInterv

block使用小结、在arc中使用block、如何防止循环引用(zz)

标签:  __block   __weak   arc   self   cfgetretaincount 分类: iOS zz from http://www.cnbluebox.com/?p=255 引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗?,发现竟然做错了几道, 才知道自己想当然的理解是错误的,所以抽时间学习了下,并且通过一些测试代

ARC模式下的循环引用引起内存泄漏

自从iOS 5时代自动引用计数(Automatic Reference Counting)技术发布,Cocoa工程师们才扔下了内存管理的包袱,从此在Objective-C修行道路上的一座大山被削平.然而,即使ARC很强大,我们日常搬砖时同样是有内存泄漏风险的,今天我就跟大家聊聊这些你可能还没有注意到的坑. 测试原理 我们知道ARC模式下,NSObject的MRC相关方法都不可以使用了,但dealloc方法如果实现了,同样还是会调用的,只是不允许在dealloc方法中调用[super deallo

如何避免在Block里用self造成循环引用

一般来说我们总会在设置Block之后,在合适的时间回调Block,而不希望回调Block的时候Block已经被释放了,所以我们需要对Block进行copy,copy到堆中,以便后用. 当一个Block被Copy的时候,如果你在Block里进行了一些调用,那么将会有一个强引用指向这些调用方法的调用者,有两个规则: 如果你是通过引用来访问一个实例变量,那么将强引用至self 如果你是通过值来访问一个实例变量,那么将直接强引用至这个"值"变量 苹果官方文档里有两个例子来说明这两种情况: 上面

block循环引用解决

block循环引用解决 实验代码 @interface ViewController ()@property (nonatomic, strong) TestNetworkBlock *testNetwork;@end @implementation ViewController (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a

解决ARC的循环引用问题

看看下面的程序有什么问题: BNRItem.h @interface BNRItem : NSObject @property (nonatomic, strong) BNRItem *containedItem; @property (nonatomic, strong) BNRItem *container; ... @end   BNRItem.m #import "BNRItem.h" @implementation BNRItem ... - (void)setContain

Unity Application Block 1.0系列(6):杜绝循环引用

在介绍 Constructor Injection.Property Injection和 Method Call Injection时,都有特别提到不要出现循环引用(Circular References),因为出现这种问题后很难去检测到.最好的解决方法是写代码时候尽量避免出现这种情况. 下面看看循环引用的几个场景,在使用依赖注入框架时应该尽量避免出现这样的情况: 1.通过Constructor Injection生成的对象在构造器的参数中互相引用 public class Class1{ p

iOS Block捕获外部变量和ARC自动拷贝block

Block内引用外部变量的问题 #define BLog(prefix,obj) {NSLog(@"位置和指针变量名:%@ ,指针内存地址:%p, 指针值:%p ,指向的对象:%@ ",prefix,&obj,obj,obj);} // 强引用 - (void)blockVariableStrongReferenceTest { NSLog(@"\n"); NSObject *obj = [[NSObject alloc] init]; BLog(@&quo