zoukankan      html  css  js  c++  java
  • block为什么用copy以及如何解决循环引用

     

      在完成项目期间,不可避免的会使用到block,因为block有着比delegate和notification可读性更高,而且看起来代码也会很简洁。于是在目前的项目中大量的使用block。
      之前给大家介绍了一下在开发的过程中使用到了代理以及block,并详细的介绍了一下delegate和block的相似之处。(如有兴趣可以去看我之前的文章         链接: http://www.cnblogs.com/MasterPeng/p/5210263.html
      主要是因为在开发的时候,有时候由于疏忽大意或者一些其他的原因,导致了使用block时造成了循环引用从而导致了内存泄露。


    block 循环引用的主要原因:在block中引用了外部变量。

      下面为大家举一个简单的例子,像下面这段代码:

      brush.getCardInfo=^(NSDictionary *info){
      [self test];
      };


      像上面这段代码,self其实是一个本地变量而不是block内部变量,如果声明为assign,代码执行到block内部就会出错。

      但是这又带来另一个问题,就是self的引用计数+1。这意味着很可能会导致循环引用。self持有brush,brush持有block,block持有self。结果就是内存泄漏。


    解决方法:
      __weak CurrentViewController *blockSelf = self; 
      brush.getCardInfo=^(NSDictionary *info){
      [blockSelf test];
      };

      通过__weak修饰变量这个方式,告诉block这个变量的引用计数不要+1。从而避免循环引用的问题。


    声明block的时候都是用copy来修饰
      使用copy修饰的原因:
      block本身是像对象一样可以retain,和release。但是,block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上。他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃。
        使用retain也可以,但是block的retain行为默认是用copy的行为实现的,因为block变量默认是声明为栈变量的,为了能够在block的声明域外使用,所以要把block拷贝(copy)到堆,所以说为了block属性声明和实际的操作一致,最好声明为copy。


    关于block更多的应用或者实现,大家可以参考巧神的一篇讲解block的博客      链接:http://blog.devtang.com/2013/07/28/a-look-inside-blocks/
  • 相关阅读:
    Maven 环境的配置
    zTree的简单例子
    plsql免安装客户端的配置
    HDU 1232 畅通工程
    HDU 5698 瞬间移动
    Codeforces 1015E1 Stars Drawing (Easy Edition)
    Codeforces 784B Santa Claus and Keyboard Check
    Codeforces 500C New Year Book Reading
    NSarray 赋值 拷贝 等问题记录
    UINavigationController 操作记录
  • 原文地址:https://www.cnblogs.com/MasterPeng/p/5311911.html
Copyright © 2011-2022 走看看