关于 __ block 再理解
我们都知道:block不准修改外部变量的值,这里所说的外部变量的值,指的是栈中指针的内存地址。__ block所起到的作用就是只要观察到该变量被block所持有,就将“外部变量”在栈中的内存地址放到了堆中。进而在block内部也可以修改外部变量的值
block不允许修改外部变量的值,apple这样设计,应该是考虑到了block的特殊性,block也属于“函数”的范畴,变量进入block,实际就是已经改变了作用域。在几个作用域之间进行切换时,如果不加上这样的限制,变量的可维护性将大大降低。
NSString 为什么必须用 __ block
@property (nonatomic, copy) NSString *testStr;
NSString *test1 = [[NSString alloc] initWithString:@"123"];
NSString *test2 = @"123";
NSString *test3 = [NSString stringWithFormat:@"123"];
NSMutableString *test4 = [[NSMutableString alloc] initWithString:@"123"];
NSString *test5 = [test4 copy];
NSString *test6 = [NSString stringWithFormat:@"%@", @"123"];
self.testStr = [test2 copy];
MyTestProject[19849:666990] 0x10bc0cf50 0x10bc0cf50 0xa000000003332313
0x608000268800 0xa000000003332313 0xa000000003332313 0x10bc0cf50
下面简单解释下:
self.testStr只是对test2的一个浅拷贝,自然地址和2一样;
3,5,6的类型都是NSTaggedPointerString,4的类型是__NSCFString。3,5,6的字面量虽然和1、2一样的,但是类型其实是不同的。
上面打印的结果中可以看到3,5,6的地址位置非常高,那它们分配在哪个区呢?
** 另外需要注意的是:如果换成较长的字符串,3,5,6的类型也不是NSTaggedPointerString而是__NSCFString **
NSString *str =[[NSString alloc]initWithString:@"4321"]; 通过alloc分配内存空间,这个时候空间是分配到堆上的。 str = @"123"; 这个时候是一个字符串常量,存储空间在栈上。 在堆上的空间需要程序员自己管理(也就是需要自己去申请alloc,和自己去释放release) 在栈上的空间是自动分配和回收的