block 实现原理(内存管理详解)(二)
在以前,MRC环境下,使用block很可能会出现内存泄漏问题,并且在以往的面试中,一些接触比较久的程序员都会喜欢问到这个问题,block内存泄漏的问题!
下面,我来介绍一下,MRC下Block内存泄漏的一个问题
先随意创建一个Dog类,并创建int类型age属性,
然后在main函数中,创建下列代码,
import “Dog.h”
int main(int argc, const char * argv[])
{
@autoreleasepool {
Dog *d = [[Dog alloc] init];
d.age = 20 ;
void(^block)() = ^{
NSLog(@"%d",d.age);
};
block();
[d release];
}
}
这个时候是正常情况,但是,如果添加如下第10行代码:
int main(int argc, const char * argv[])
{
@autoreleasepool {
Dog *d = [[Dog alloc] init];
d.age = 20 ;
void(^block)() = ^{
NSLog(@"%d",d.age);
};
Block_copy(block);
block();
[d release];
}
}
此时此刻,有人想对block进行release,但是不管你是否对block进行release ,都无法释放d对象。为什么呢??
这个时候,我们就要对block进行分析了:
1.默认情况下, block的内存是在栈中
* 它不会对所引用的对象进行任何操作
2.如果对block做一次copy操作, block的内存就会在堆中
* 它会对所引用的对象做一次retain操作
* 非ARC : 如果所引用的对象用了__block修饰, 就不会做retain操作
* ARC : 如果所引用的对象用了__unsafe_unretained\__weak修饰, 就不会做retain操作
所以,只需要在Dog类前面加上__block即可!