zoukankan      html  css  js  c++  java
  • 来回顾下block

    block,块语句

    首先这个东东有点类似于 C语言的函数指针,但是他又不是函数指针。。。

    原因是,函数指针只能操作全局变量和自己函数里面的变量,而block不同,他都能操作,只要你能想办法传给他。

    而这个block呢,实际上是个什么神奇的东东呢,没错,他是一个NSObject的一个派生类,任意一个block都是一个对象,他就像一个大型的工厂类,比较特殊,具体,往下看

    说到block不得不说为之引进的__block,

    不多说,来看看代码就能很直观的知道__block的一个功能

    这种写法完全没有问题,执行这个block语句,打印a的值。

    没问题,完全可以正常打印,但是如果如果你想更改a的值,那么你回发现截图中的问题:

    当你使用__block之后,你可以对这个值进行修改,

    输出结果

    这就是__block主要的作用就是,嗯可以这么理解,在不使用的时候,是值的传递,不能修改滴,当使用之后就是引用了,可以改变值了。

    当然这只是比较简单的描述,具体的情况看看这篇博文

    http://blog.csdn.net/jasonblog/article/details/7756763

    从这里面就可以看出block的本质和一些他的实现。

    接着我们来看3种情况打印关于block的结果

    定义

    typedeflong (^myBlock)(int, int);

    这个是在MRC

    这个是在ARC下

    关于这个第二个问题,我也不知道该怎么解释了,总之,这就是这2个的最大区别之一!另外一个区别,仔细瞅瞅,ARC下copy的结果居然是一样的。

    咱们继续往下看:

    根据Block在内存中的位置分为三种类型NSGlobalBlock,NSStackBlock, NSMallocBlock。

    • NSGlobalBlock:类似函数,位于text段;
    • NSStackBlock:位于栈内存,函数返回后Block将无效;
    • NSMallocBlock:位于堆内存。

    为什么blk1类型是NSGlobalBlock,而blk2类型是NSStackBlock?

    blk1和blk2的区别在于,blk1没有使用Block以外的任何外部变量,Block不需要建立局部变量值的快照,这使blk1与函数没有任何区别,

    从blk1所在内存地址0x47d0猜测编译器把blk1放到静态区。blk2与blk1唯一不同是的使用了局部变量base,在定义(注意是定义,不是运行)blk2时,局部变量base当前值被copy到栈上,作为常量供Block使用。

    额,由上面这句话我们在回到之前使用__block的情况,如果说是拷贝出来然后使用,那么我们来看看下面的代码是怎么样的结果

    首先这个 第一行的输出150的结果,很好理解,100+50嘛,为什么不是250,我觉得问这个问题的就不适合来看这篇文章!

    下面的是 第二行的输出270 ,这个是block输出的结果,简单不用说。

    第三行是输出250,那么也就是100+100+50,,额,如此简单是不!

    但是反过来想想,上面一句话不是说吧这个值copy到栈上了,然后操作的话,那么num的值在经过第二次答应之后第三次的记过不就是150么,怎么变成250了。。。

    又回到上面所说的__block这个修饰,实际上是类似于c++的引用,指针是同一个,改变的一直都是那个值。

    这样也就能彻底的区分开了__block和__weak的差别了!

    另外在ARC和MRC下都是在NSStackBlock下的情况如下:

     这种情况相信结合之前别的博客里面的就很好理解了,block本来是被分配在栈区的,根据上面的那个MRC情况下的第二种可以看出,但是在ARC下也是如此的,只是arc下默认的会是__strong来修饰一个变量,估计跟它的默认帮你管理内存机制有关,

    来看看这张图,很好的诠释的ARC下里面分配内存的情况:

    另外这个block块里面必须要引用进来一个值,这个值是什么都行,但必须是block外面的,如果不引用或是直接打印一行语句什么的,都会是NSGlobalBlock!

    然后就是关于block的常用方法,

    说到这里常用的方法都应该知道,主要是 __block和__weak这两个的问题

    前面那个连接中可以看出__block实质是在做一件事&取指向指针的指针,那么用__block修饰过的对象在传入block中的时候是不会对该对象进行计数加1的

    那么在ARC下

    __weak这个在ARC下才有的,用来使对象被弱引用,并在释放后置空。

    __block也不会强引用对象,就引用对象方面,到底有什么区别呢?

    为此我来测试了一下:

    这里用到了一个特别的类,

    [NSHashTable weakObjectsHashTable];在ARC下专用

    设置为单例的存在,然后定义了2个vc,在其中一个里面设置2个button,

    然后设定这个av为属性的时候和非属性时的各种情况,最后发现,

    当av为Strong属性时,我使用__block来修饰self是会泄露的,而__weak不会

    当av为实例变量时,同和strong属性

    当av为局部变量时,两者效果一样。。。__strong因为他是局部变量不会被self给持有。

    所以在ARC下使用__weak来修饰你的self吧,避免循环引用!!

    因为你不可能在block里面去改变当前self的指针这个值,所以,也就是用来对应用assgin来修饰的值吧。

    好了总结告一段落!

    感谢百度,谷歌,还有前人们

  • 相关阅读:
    使用SignalR实现即时通讯功能
    SignalR入门篇
    Mongodb关闭开源许可感想
    RaspberryPi学习教程系列4(串口通信篇)
    RaspberryPi学习教程系列3(编程实验篇-双色LED实验)
    RaspberryPi学习教程系列1(系统安装篇)
    RaspberryPi学习教程系列2(编程前准备篇)
    关于Entity Framework,园里有非常多误人子弟的`
    Java多线程1:使用多线程的几种方式以及对比
    Django编写RESTful API(六):ViewSets和Routers
  • 原文地址:https://www.cnblogs.com/lingzhiguiji/p/3701666.html
Copyright © 2011-2022 走看看