Block简单理解

作者: 云之君兮鹏 | 来源:发表于2016-04-04 11:40 被阅读225次

    Block块的一点总结

    希望大家指正 共同进步
    • block是一个匿名函数
    • Block定义分为三个部分:返回值类型,参数列表,block实体部分{}
     返回值类型(^block名字)(参数)=^
    
      {
    
          如果有返回值,那么使用return;
    
     }```
    
     
    - OC语言中有三种block
    ```  /**
    
      *_NSConcreteGlobalBlock:全局静态block 不会访问任何外部变量
    
      *_NSConcreteStackBlock:保存在栈区的block,当函数返回时会被销毁
    
      *_NSConcreteMallocBlock:保存在堆区block 引用计数为0时,会被销毁;
    */```
    
    - 第一问:在block内部是否可以访问外部变量  答:可以
    - 第二问:在block内部你能否改变外部变量的值    答:不可以
    - 第三问:内外变量地址是否一样        答:不一样
    ````   int i=0;````
    ``` NSLog(@"外部%p",&i);```
    
    ```void(^block1)()=^void()
    {
    NSLog(@"内部访问外部变量%d",i);
    i=20;错误
    NSLog(@"内部%p",&i);
    }```;
    ``block1()``;
    
    - 第四问:如果我们想改变外部变量怎么办
    答: 使用static全局修饰
    - 第五问:不允许使用全局修饰
    答:使用__block  杠杠两个杠修饰变量
    
    >block与blok外部定义的变量之间的关系,在block中可以访问局部变量 不能修改
    block与__block之间修饰的局部变量之间的关系,可以修改可以访问
    block与static修饰的静态变量关系可以访问可以修改
    
    
    > 举例分析:
     __block int i=0;
    int j=0;
    int *q=&j;
    int* p =&i;
    NSLog(@"\n1---外部i=%d,j=%d,i的地址%p,i指针p的地址%p,q的地址%p",i,j,&i,&p,&q);
    void(^b1)()=^void()
    {
     *p=*p+1;
     *q=*q+1;
    NSLog(@"\n2---内部i=%d,j=%d,i的地址%p,i指针p的地址%p,q的地址%p",i,j,&i,&p,&q);
    };
    b1();
    i=i+1;
    j=j+1;
    NSLog(@"\n13---外部i=%d,j=%d,i的地址%p,i指针p的地址%p,q的地址%p",i,j,&i,&p,&q);
    
      /**
    
      结果如下
    
     ``` 1---外部i=0,j=0,i的地址0x7fff5e252df8,
    
      i指针p的地址0x7fff5e252dc8,
    
      q的地址0x7fff5e252dd0
    
      2---内部i=0,j=0,i的地址0x7ffb1bc184f8,
    
      i指针p的地址0x7ffb1bc3a078,
    
      q的地址0x7ffb1bc3a080
     3---外部i=1,j=2,i的地址0x7ffb1bc184f8,
    
      i指针p的地址0x7fff5e252dc8,
    
      q的地址0x7fff5e252dd0
    依次分析:
    
      __block修饰的i 在block内部复制他的内容重新开辟了空间,并且让他也变成和内部一样的地址, 也就是也可以访问也可以修改*p是i原来的地址上的值改变了也不会影响新的地址上的值 最后执行block内部的时候i=0(从原来的地方拷贝的)出来后加1变成1;
      j 未被修饰 内部打印是拷贝过来的换了(开辟)空间存的值0,*q=*q+1这一步里面q变量在内部换了自己地址但是存的内容是j的值地址所以改变了外部变量j(0)的值(0+1) 出了blockj的值变成1再加1最后是外部打印变为2
      j, p, q,这三个变量均没有被__block修饰所以在内部会开辟空间把值复制过去从而进行访问,出来后还是原来的地址    */````
    
    
    - __weak和__block
    
    ```` //1__block在ARC 和 MRC下都能使用_weak只能在ARC下
    //2__weak只能修饰对象__block都可以修饰
    //3__block在block里面可以重新复制.__weak不可以
    //4_block引起引用计数_weak不会````
    - block写成copy1是为了安全 2是从栈区拷贝到堆区block在栈区存在时间随生命周期,在堆区我们随时调用````

    相关文章

      网友评论

      本文标题:Block简单理解

      本文链接:https://www.haomeiwen.com/subject/abeulttx.html