Block的定义
Block是将函数及其执行上下文封装的一个对象
Block的类型
-
__NSGlobalBlock__ ( _NSConcreteGlobalBlock ) -
__NSStackBlock__ ( _NSConcreteStackBlock ) -
__NSMallocBlock__ ( _NSConcreteMallocBlock )
其中三种不同的类型和环境对应如下
| block类型 | 环境 |
|---|---|
__NSGlobalBlock__ | 没有访问auto变量 |
__NSStackBlock__ | 访问了auto变量 |
__NSMallocBlock__ | __NSStackBlock__调用了copy |
其在内存中的分配如下对应
Block在内存上的位置的验证
先看一个问题,下面的myBlock指针指向的对像存储的位置,是在堆区、栈区、还是数据区?
int main(int argc, const char * argv[]) {
@autoreleasepool {
BEBlock myBlock = ^{
NSLog(@"hello world");
};
}
return 0;
}
先告诉大家结果,我也觉得很神奇,这个block对象存储的位置竟然是数据区。
为了验证Block在内存上的具体存储位置,我打印几个变量来辅助验证其存储位置,具体的看如下代码:
int main(int argc, const char * argv[]) {
@autoreleasepool {
int height = 10.0;
static int age = 20;
BEPerson * person = [[BEPerson alloc] init];
BEBlock myBlock = ^{
NSLog(@"hello world");
};
NSLog(@"--address-- %p", &height);
NSLog(@"--address-- %p", &age);
NSLog(@"--address-- %p", &person);
NSLog(@"--address-- %p", &myBlock);
NSLog(@"\n\n");
NSLog(@"---value--- %d", height);
NSLog(@"---value--- %d", age);
NSLog(@"---value--- %@", person);
NSLog(@"---value--- %@", myBlock);
}
return 0;
}
打印结果:
--address-- 0x7ffeefbff42c
--address-- 0x100008124
--address-- 0x7ffeefbff420
--address-- 0x7ffeefbff418
---value--- 10
---value--- 20
---value--- <BEPerson: 0x101019570>
---value--- <__NSGlobalBlock__: 0x100004058>
结论:
height、peeson指针,myBlock指针都是0X7ffeebff--,所以它们3是存在栈区的。age用的是static变量来修饰的,所以其存在数据区。
然后看myBlock对象,其地址值是0x100004058和age的地址0x100008124比较接近,所以可以判断,myBlock对象是存储在数据区的。
person对象,其地址值是0x101019570 ,存在堆区。
- height是存在栈区
- age在数据区
- person指针是在栈区,但是其指向的对象,是在堆区
- myBLock指针是在栈区,但是其指向的对象,是在数据区
参考资料: