Block
本质来讲是OC 对象,其内部有一个isa指针。
1 Block 的声明
一言以蔽之: returnType ( ^blockName)(parameterTypes) = ^returnType (parameters) {};
- returnType 返回的类型 可以为Void,为Void的时候可以省略
- ^blockName Block的名字
- parameterTypes 参数类型
- parameters 变量的名字
// 1 有返回值 有参数
int(^Sum)(int,int) = ^int (int a, int b){
return a + b;
};
NSLog(@"%d",Sum(5,5));
// 2 无返回值有参数
void (^SayHi)(NSString *) = ^(NSString *hello){
NSLog(@"hello-%@",hello);
};
SayHi(@"China");
// 3 无返回值无参数
void (^Run)(void) = ^{
NSLog(@"Nothing happend");
};
Run();
我在代码中常用的定义的方式
-
@property (copy,nonatomic)void(^openBtnClickBlock)(BOOL);
-
typedef void(^SKBlock)(NSString *);
2 本质是什么?
本质是OC 对象
cd 到文件夹 执行命令行,生成main.cpp
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m
找到main 删除 copy 出来 咱们的OC 代码转为C++ 之后的代码
void (*Run)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
// __main_block_impl_0 的定义如下
// 其中的__block_impl 存放的是一些变量信息,其中存在isa指针,本质上还是一个OC的对象
// 然后就是初始化构造函数
// __main_block_desc_0 这是block 的描述信息
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
// 构造函数 返回的是结构体对象
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
// __block_impl 定义如下
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
// __main_block_func 如下
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
NSLog((NSString *)&__NSConstantStringImpl__var_folders_fy_885kj4n56w7g9r9_jkpsn25h0000gp_T_main_2c916c_mi_0);
}
// __main_block_desc_0_DATA 定义
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
3 Block 的类型
通过class 方法 或者isa 指针可以查看具体类型。
- 1 NSGlobalBlock 没有访问auto 变量 内存分配在数据区域
- 2 NSStackBlock 访问了auto 变量 内存分配在栈区域
- 3 NSMallocBlock NSStackBlock 调用了copy 方法,没存分配在堆区域
每一种的类型的block 复制之后的结果
int meters = 1000;
// 3 无返回值无参数
void (^Run1)(void) = ^{
NSLog(@"i have run %d meters",meters);
} ;
Run1();
void (^Run2)(void) = ^{
NSLog(@"i have run");
} ;
Run2();
void (^Run3)(void) = [^{
NSLog(@"i have run %d meters",meters);
} copy];
Run3();
// 之所以 没有stack Block 是因为 ARC 环境导致的 自动进行copy stackBlock 的操作
// 打印结果 __NSMallocBlock__--__NSGlobalBlock__--__NSMallocBlock__
NSLog(@"%@--%@--%@",[Run1 class],[Run2 class],[Run3 class]);

3004

被折叠的 条评论
为什么被折叠?



