iOS学习总结iOS DeveloperiOS技巧操作

Block简单理解

2016-04-04  本文已影响225人  云之君兮鹏

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在栈区存在时间随生命周期,在堆区我们随时调用````
上一篇下一篇

猜你喜欢

热点阅读