为什么在block中不能修改局部变量?
之前的关于__block结构体和Block结构体内容就不介绍了,下面根据这个例子做理解:
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:10];
int age = 10;
static int age1 = 10;
[array addObject:[Person new]];
[array addObject:[Person new]];
[array addObject:[Person new]];
NSLog(@"%p---%p---%p---%p",array,&array,&age,&age1);
NSLog(@"-------------------------------");
self.block = ^{
[array addObject:[Person new]];
NSLog(@"%p---%p---%p---%p",array,&array,&age,&age1);
};
//主要的输出内容
2021-09-08 11:09:33.708449+0800 BlockTest[99745:25780878] 0x600000b1dec0---0x7ffee0eec058---0x7ffee0eec054---0x10ed19718
2021-09-08 11:09:33.708586+0800 BlockTest[99745:25780878] -------------------------------
2021-09-08 11:09:42.859042+0800 BlockTest[99745:25780878] 0x600000b1dec0---0x600000b0cf20---0x600000b0cf28---0x10ed19718
这里说明一下,通过测试,这里的array和age都不能在block中修改(array的不能修改指的是 array = nil).
从打印可以看出,&age和&array(一下用&表示内存地址)的地址在block内外是不一样的,通过对block本质的理解可以知道,block内部的&只是在block函数内部,所以你对&内存的修改只是针对函数内部的,并不会影响外部的&内的内容,这种操作实际是不符合block的定义的,所以苹果不允许这样操作.
但是细心的朋友可以看到,对[array add]是可以的,其实这里也是很好理解的,虽然之前说&是不一样的,但是&中的内容是一样的,只不过age是值类型,内外的&都存储这10这个值,array是指针类型,内外&中都存储这array的堆地址,我通过&内容(后面用&表示)去操作&里面的内容实际是跟block没有关联的,这里并没有修改&中的内容,
所以不管是基本数据类型还是对象类型的局部变量(或者说值类型和指针类型),都不可以在block中直接修改内容,如果要修改只能通过__block修饰的方法.
其实我们发现这里的本质是不能修改block内部的局部变量
,而局部变量内部的操作就跟block没有关系了,所以为什么要用__block包裹是不是就很好理解了.
网友评论