数据类型如下
- 局部变量
- 静态变量
- 全局变量
- blcok变量
下面是code
局部变量
//局部变量
- (void)testLocalData {
int temp = 10;
NSLog(@"outside temp --- >%p", &temp);
int (^sum)(int,int) = ^(int a, int b) {
NSLog(@"inside temp --- >%p", &temp);
return temp + a +b;
};
temp = 0;
int c = sum(1,2);
NSLog(@"last c --- >%d",c);
}
打印结果
2017-12-27 15:56:52.405071+0800 ManagerBlockMemory[7031:472834] outside temp --- >0x7ffee6bceb2c
2017-12-27 15:56:56.002926+0800 ManagerBlockMemory[7031:472834] inside temp --- >0x600000447010
2017-12-27 15:57:04.070374+0800 ManagerBlockMemory[7031:472834] last c --- >13
(lldb)
静态常量
//静态变量
- (void)testStaticData {
static int staticTemp = 10;
NSLog(@"outside staticTemp --- >%p", &staticTemp);
int (^sum)(int,int) = ^(int a, int b) {
NSLog(@"inside staticTemp --- >%p", &staticTemp);
return staticTemp + a +b;
};
staticTemp = 0;
int c = sum(1,2);
NSLog(@"last staticTest c --- >%d",c);
}
打印结果
2017-12-27 15:59:32.602313+0800 ManagerBlockMemory[7031:472834] outside staticTemp --- >0x109031020
2017-12-27 15:59:34.118012+0800 ManagerBlockMemory[7031:472834] inside staticTemp --- >0x109031020
2017-12-27 15:59:35.782439+0800 ManagerBlockMemory[7031:472834] last staticTest c --- >3
全局变量
//全局变量
- (void)testGlobalData {
NSLog(@"globalData---->%p",&globalTestData);
int (^sum)(int,int) = ^(int a, int b) {
NSLog(@"globalData---->%p",&globalTestData);
return globalTestData + a + b;
};
globalTestData = 0;
int c = sum(1,2);
NSLog(@"globalData --%d",c);
}
打印结果
2017-12-27 16:02:58.856153+0800 ManagerBlockMemory[7031:472834] globalData---->0x7fa304e1c710
2017-12-27 16:03:02.124012+0800 ManagerBlockMemory[7031:472834] globalData---->0x7fa304e1c710
2017-12-27 16:03:04.211810+0800 ManagerBlockMemory[7031:472834] globalData --3
block变量
//blcok变量
- (void)testBlockData {
__block int blockData = 10;
NSLog(@"blockData-- %p",&blockData);
int (^sum) (int, int) = ^ (int a, int b){
NSLog(@"blockData-- %p",&blockData);
return blockData + a + b;
};
blockData = 0;
int c = sum(1,2);
NSLog(@"blk test c --- %d",c);
}
打印结果
2017-12-27 16:04:24.820931+0800 ManagerBlockMemory[7031:472834] blockData-- 0x7ffee6bceb28
2017-12-27 16:04:27.759598+0800 ManagerBlockMemory[7031:472834] blockData-- 0x604000628078
2017-12-27 16:04:30.801036+0800 ManagerBlockMemory[7031:472834] blk test c --- 3
上面的4个案列中,分别是对block中遇到的局部变量,静态常量,全局变量和block变量的测试。
可以看到,全局变量 和 静态变量类型时,变量的地址没有变化,由于全局变量和静态变量的内存地址是固定的,block在定义变量的时候,是直接读取的内存地址,没有复制变量值。
再来看本地变量和block变量,在block中内存地址是改变的,但是在方法sum()中,得到的结果却不一样。
对于局部变量,block在定义的时候复制了它,没有复制变量的内存地址,它在block中是作为常量使用的,是不能被修改的,其值不受外面的影响,
对于block变量,可以看到其地址发生了变化,但是blockData却受到外界影响。这是因为,blockData在定义变量本身的时候是位于stack(栈)上的,而在定义block的时候,该变量并不是被复制了一份,而是编译器将其转移到了heap(堆)上,下面是测试代码
- (void)testBlockData {
__block int blockData = 10;
NSLog(@"blockData-- %p",&blockData);
int (^sum) (int, int) = ^ (int a, int b){
NSLog(@"blockData-- %p",&blockData);
return blockData + a + b;
};
NSLog(@"blockData-- %p",&blockData);
blockData = 0;
int c = sum(1,2);
NSLog(@"blk test c --- %d",c);
}
下面是输出
2017-12-27 16:40:30.971155+0800 ManagerBlockMemory[7445:512216] blockData-- 0x7ffeef5d7b28
2017-12-27 16:40:30.971420+0800 ManagerBlockMemory[7445:512216] blockData-- 0x60000003f458
2017-12-27 16:40:35.657576+0800 ManagerBlockMemory[7445:512216] blockData-- 0x60000003f458
2017-12-27 16:40:38.758031+0800 ManagerBlockMemory[7445:512216] blk test c --- 3
总结一下:
局部变量是以值传递的方式传递到block里。block值捕获block中会用到的变量,由于只捕获了局部变量的值,非内存地址,多以block内部不能修改局部变量的值。
Block捕获的外部变量可以改变值的是静态变量,block变量,全局变量.
有的博客写到,在Block中改变变量值有2种方式,
一是传递内存地址指针到Block中,
二是改变存储区方式(__block)
第二种要好好研究下
参考博客:
深入研究Block捕获外部变量和__block实现原理