一、静态变量 和 全局变量 以及 可变对象(NSMutableArray,NSMutableString)的变量
在加和不加 __block 都会直接引用变量地址。也就意味着 可以修改变量的值。在没有加__block 参数的情况下。
以下所有block 均为
=<__NSStackBlock__: 0x7fff5829e9c0> 栈block ,且 MRC 环境。
NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithObjects:@"asfd", nil]; NSMutableString *metableStr = [NSMutableString stringWithString:@"metableStr"] ; void (^print)(void) = ^{ [mutableArray addObject:@"haha"]; [metableStr appendString:@"_hello"]; NSLog(@"=array========%ld====%@",[mutableArray retainCount],mutableArray); NSLog(@"=metableStr=======%@", metableStr); } [metableStr appendString:@"_hello_"]; [mutableArray addObject:@"sdfsfdsf"]; NSLog(@"======%@",print); print();
打印内容是: block 内
=array========1====(
asfd,
sdfsfdsf,
haha
)
=metableStr=======metableStr_hello__hello
二, 常量变量(NSString *a = @"hello";a 为常量变量,@“hello”为常量。)-----不加__block类型 block 会引用常量的地址(浅拷贝)。加__block类型 block会去引用常量变量(如:a变量,a = @"abc".可以任意修改a 指向的内容。)的地址。
如果不加__block 直接在block 内部修改变量 ,会编译报错。block 内部改变量是 只读的。
但是 就一定可以推断 block 会深拷贝 该变量吗???
对于常量 @“hello” 存储在 内存中的常量区, 程序结束才会释放 内存。 如:
NSString *str = @"hello";
NSString *abcStr = @"hello";
编译器会优化处理, str 和 abcStr 都会指向 常量区的@“hello” 地址。
NSString *str = @"hello"; void (^print)(void) = ^{ NSLog(@"block=str======%p",str); } str = @"hello1"; print();
block 会拷贝变量内容到自己的栈内存上,以便执行时可以调用。 但并不是对str 内容做了深拷贝,重新申请内存。
因为str 是栈内存上的变量,指向 一个常量区的@“hello”. 编译器做的优化是 当block 去拷贝str 指向内容时发现是个常量,
所以会去引用 @“hello” 的指针,没必要再取申请一块内存。
复习下内存分类: http://blog.csdn.net/u011848617/article/details/39346075