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

浙公网安备 33010602011771号