当前位置:网站首页>Three types of [OC learning notes] Block
Three types of [OC learning notes] Block
2022-08-02 08:29:00 【Billy Miracle】
Block的三种类型
block的类型,取决于isa
指针,可以通过调用class
方法或者isa
指针查看具体类型,最终都是继承自NSBlock
类型.
使用如下代码:
void testBlockType(void) {
int age = 10;
void(^block1)(void) = ^{
NSLog(@"block1----");
};
void(^block2)(void) = ^{
NSLog(@"block2----%d", age);
};
NSLog(@"block1-----%@ %@ %@ %@", [block1 class], [[block1 class] superclass], [[[block1 class] superclass] superclass], [[[[block1 class] superclass] superclass] superclass]);
NSLog(@"block2-----%@ %@ %@ %@", [block2 class], [[block2 class] superclass], [[[block2 class] superclass] superclass], [[[[block2 class] superclass] superclass] superclass]);
NSLog(@"block-----%@ %@ %@ %@", [^{
NSLog(@"block----%d", age);
} class], [[^{
NSLog(@"block----%d", age);
} class] superclass], [[[^{
NSLog(@"block----%d", age);
} class] superclass] superclass], [[[[^{
NSLog(@"block----%d", age);
} class] superclass] superclass] superclass]);
}
打印结果:
三个block的类型分别为:__NSGlobalBlock__
、__NSMallocBlock__
、__NSStackBlock__
The above three types are ultimately inherited fromNSBlock
,而NSBlock
又是继承自NSObject
:further explained hereblock其实就是一个OC对象.
- NSMallocBlock(_NSConcreteMallocBlock) 对象存储在堆区
- NSStackBlock(_NSConcreteStackBlock) 对象存储在栈区
- NSGlobalBlock(_NSConcreteGlobalBlock)对象存储在数据区
换到MRCEnvironment to try:
MRC模式下,三种block类型:__NSGlobalBlock__
、__NSStackBlock__
、__NSStackBlock__
,Why is the type in the middle given bymalloc
变成了stack
?这是因为ARCautomatically help usblock
进行了copy
操作.
分析
Let's try to convert firstC++Code view type:
struct __testBlockType_block_impl_0 {
struct __block_impl impl;
struct __testBlockType_block_desc_0* Desc;
__testBlockType_block_impl_0(void *fp, struct __testBlockType_block_desc_0 *desc, int flags=0) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
struct __testBlockType_block_impl_1 {
struct __block_impl impl;
struct __testBlockType_block_desc_1* Desc;
int age;
__testBlockType_block_impl_1(void *fp, struct __testBlockType_block_desc_1 *desc, int _age, int flags=0) : age(_age) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
struct __testBlockType_block_impl_2 {
struct __block_impl impl;
struct __testBlockType_block_desc_2* Desc;
int age;
__testBlockType_block_impl_2(void *fp, struct __testBlockType_block_desc_2 *desc, int _age, int flags=0) : age(_age) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
发现都是_NSConcreteStackBlock
类型.cannot respond correctlyblock
的实质类型(可能是LLVMCompiler version problem,而clang又是LLVM的一部分).
In addition to the heap area, the program partition requires the programmer to manually manage memory,Other areas are automatically managed by the system.
{
//等号左边:autoshape local variable,存放在栈区;
//等号右边:常量,存放在数据区;
int age = 10;
//等号左边:autoshape local variable(指针),存放在栈区;
//等号右边:autoshape local variable address,存放在栈区;
int *agePtr = &age;
//等号左边:autoshape local variable(指针),存放在栈区;
//等号右边:allocopen object,存放在堆区;
NSObject *objc = [[NSObject alloc] init];
}
三种block类型(global、malloc、stack),从字面理解,Can be concluded that, in turn, stored in a data area、堆区、栈区;blcok1
没有访问任何变量,后两个block
both access variablesage
,而age
是一个auto
类型的局部变量.
int height = 150;
void testBlockType(void) {
int age = 10;
static int weight = 80;
void(^block1)(void) = ^{
NSLog(@"block1----");
};
void(^block2)(void) = ^{
NSLog(@"block2----%d", age);
};
void(^block3)(void) = ^{
NSLog(@"-----%d", weight);
};
void(^block4)(void) = ^{
NSLog(@"-----%d", height);
};
NSLog(@"%@ %@", [block3 class], [block4 class]);
}
结果:
如果是static
修饰的局部变量,or access global variables,则block
的类型都是__NSGlobalBlock__
,then it is almost certain,block
The type can depend on the properties of the variable it accesses.
因为auto
Local variables of type are stored in the stack area,而block
to access the variable,After the previous analysis,block
will capture the variable inblock
结构体内部,Is to create a memory to store the local variable(相当于copy
操作,但不是copy
),那么此时的block
Where do you store yourself in??前面说了,auto
Local variables of type must be stored in the stack area,这点毋庸置疑,而block
Although newly opened memory to store the variable,But can't change the variable is aauto
properties of local variables of type,因此此时的block
can only be stored in the stack area;Since it is stored in the stack area,then the scope of the variable accessed is limited to the scope of the nearest brace,If it exceeds, it will be automatically released.
MRC下测试下面代码:
void(^block4)(void);
void test3()
{
int age = 10;
block4 = ^{
NSLog(@"----%d", age);
};
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
test3();
block4();
// NSLog(@"%@", [block4 class]);
}
return 0;
}
输出:
说明age
Has been released automatically,block
再次调用时,Access to discarded memory.手动copy
:
void(^block4)(void);
void test3()
{
int age = 10;
block4 = [^{
NSLog(@"----%d", age);
} copy];
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
test3();
block4();
NSLog(@"%@", [block4 class]);
}
return 0;
}
结果:
因为copy
是把age
The value is directly copied to a new memory area,而我们知道copy
Create a memory must be in the heap area operations(同时,block
The type is changed from the previous__NSStackBlock__
类型变为__NSMallocBlock__
类型).因此,防止一个auto
Type of local variables automatically release method,就是将其copy
To the heap area manual management,To achieve the purpose of controllable life cycle(So remember to release[block release]
)——这是MRCManually manage memory in mode,而在ARCIn this mode, the system will automatically manage the memory(copy
和release
).
边栏推荐
猜你喜欢
随机推荐
MGRE综合实验
多版本node的安装与切换详细操作
五款优秀免费的在线抠图工具
EPSANet: An Efficient Pyramid Split Attention Block on Convolutional Neural Network
mysql如何从某一行检索到最后
PostgreSQL学习总结(11)—— PostgreSQL 常用的高可用集群方案
.NET静态代码织入——肉夹馍(Rougamo) 发布1.1.0
WebRTC系列-SDP之编码信息收集
HCIP第二天
Biotin hydrazide HCl|CAS:66640-86-6|生物素-酰肼盐酸盐
CASA模型、CENTURY模型应用与案例分析
HCIP 第十天
Stop mental exhaustion Daily sharing
Biotin hydrazide HCl|CAS:66640-86-6|Biotin-hydrazide hydrochloride
Postgres horizontal table, automatically create partitions, table by time
flutter 自己写一个组件
Database Plus 的云上之旅:SphereEx 正式开源 ShardingSphere on Cloud 解决方案
典型的一次IO的两个阶段是什么?阻塞、非阻塞、同步、异步
redis-advanced
下一个排列