在block内如何修改block外部变量?
1、Block中不允许修改外部变量的值。这里所说的外部变量的值,指的是栈中指针的内存地址。__block修饰之后,立马将“外部变量在栈中的内存地址放到堆中”,如果不做特殊修改就一直在堆中,进而做到在block内部修改外部变量。
2、大小比较:堆地址要小于栈地址。iOS中一个进程的栈区内存只有1M,Mac也只有8M。
3、这里的a已经由基本数据类型,变成了对象类型。block会对对象类型的指针进行copy,copy到堆中,但并不会改变该指针所指向的堆中的地址
__block int a = 5;
NSLog(@"定义前:%p",&a); // 1、栈中
void (^foo)(void) = ^{
a = 6;
NSLog(@"block内部:%p",&a); //3、堆中
};
NSLog(@"定义后:%p",&a);//2、堆中
foo();
定义前:0x16fda86f8
定义后:0x155b22fc8
block内部: 0x155b22fc8
NSMutableString *a = [NSMutableString stringWithString:@"Tom"];
NSLog(@"\n 定以前:------------------------------------\n\
a指向的堆中内存对象的地址:%p;a在栈中的指针地址:%p", a, &a);
void (^foo)(void) = ^{
a.string = @"Jerry";
NSLog(@"\n block内部:------------------------------------\n\
a指向的堆中内存对象的地址:%p;a在栈中的指针地址:%p", a, &a);
// a = [NSMutableString stringWithString:@"William"];
};
foo();
NSLog(@"\n 定以后:------------------------------------\n\
a指向的堆中内存对象的地址:%p;a在栈中的指针地址:%p", a, &a);
