IOS使用Block —— 3 Block的两个注意点

首先普及一下内存存储区域知识:

内存分为五大区域:堆、栈、全局区、文字常量区、代码区
 
堆存放:由new、alloc分配的内存块,由程序员控制释放     p1 = (char *)malloc(10); 
栈存放:存放函数参数、局部变量,在不需要的时候由编译器自动清除的变量存储区。   int b;   char s[] = “abc”;   char*p2;
全局区(静态):全局变量和静态变量存储放在一块的,程序结束后由系统释放
文字常量区:常量字符串放在这里,程序结束系统释放
代码区:存放函数体的二进制代码 
 

1    block在MRC下的内存隐患
 
问题:
1 - 下面这段代码在ARC中是否存在问题?
     不存在
2 - 下面这个代码在MRC中是否存在问题?
     存在,设置block后,在合适的时间回调block,不希望block被释放,所以要对block进行copy
 
typedef void (^blockType)();
// 定义返回值是block类型的函数
blockType test() {
    int i = 5;
    blockType bb = ^{
          NSLog(@“xxxx i = %d”, i);
     }
     // return bb;   // 防止被释放,copy到堆区,所以需要改为  return Block_copy(bb);
     return Block_copy(bb);
}
int main() {
    @autoreleasepool {
          // 接收test的返回值
          blockType b1 = test();
          // 执行block
          b1();
          // MRC下copy到堆区一份,需要释放该block的控件,所以需要添加一句   Block_release(b1());
           Block_release(b1());
     }
}

 


  
2  block循环引用
 
发现问题:
控制器中对Block进行copy,copy后对block进行一个强引用,block中的self对控制器进行强引用,所以造成了一个强引用环,互相无法释放
 
 
解决问题:
打破强引用环只要将block中的 self 变成弱指针,即可解决;
// 这个神奇的方法就是:
__weak typeof(self) weakSelf = self;   // 将block中的self改为weakSelf

 

 
 
最后本人在查阅过程中翻过的帖子贴上:
——————内存————————
堆栈区别:http://blog.csdn.net/aixiaolin/article/details/6863991
区域划分:http://blog.csdn.net/wealoong/article/details/8686353
——————block————————
ARC与非ARC下block属性问题:http://www.mgenware.com/blog/?p=1493
容易引起“循环引用”的三种场景:http://www.2cto.com/kf/201409/332193.html
block使用测试:http://www.cocoachina.com/bbs/read.php?tid=152222&page=1
 
posted @ 2015-09-03 15:24  秦锐IOS  阅读(371)  评论(0编辑  收藏  举报