Block是带有自动变量值的匿名函数,这个大家都知道。那他底层是怎么实现的呢,他是怎么做到的呢
1.首先来看C代码,函数指针!
float a=1,b=2, c;
float (*p)(float x, float y);
p=max;
c=(*p)(a,b);
printf("\nmax=%f",c);
/*等效于 max(a,b)*/ printf("\nmax=%f",c);
p=min;
c=(*p)(a,b); /*等效于min(a,b)*/ printf("\nmin=%f",c);
printf("\nmin=%f",c);
/*
##这样是没有意义的
*/
void (*t)();
t= test;
funcss(1, t);
/*类似Block 的使用*/
int (*sum)(int a,int b);
sum = testsum;
int v = sum (10,20);
NSLog(@"%d",v);
}
int testsum(int a,int b){
return a+b;
}
void test(){
printf("进来了");
}
void funcss (int a ,void* funcname){
}
float max(float x,float y){
printf("Max come hers");
return x>y?x:y;
}
float min(float x,float y){
printf("Min come hers");
return x
}
上面C函数 只是告诉读者,往本质上去想问题。
下面我在 程序入口写了一个block
int main() {
void (^blk)(void) = ^{
printf("block\n");
};
blk();
return 1;
}
/*大家都是OC底层是C写的,都是动态调用的,在每个对象实例化,其实都是在发alloc init消息。//Runtime objc_megSend (objc_getClass),Sel_registerName(alloc)
1.C的函数就是把他结构体的指针传递放进去,然后进行赋值处理。
*/
***C 转化与OC C++转化方法 类的实例化方法函数,
void Myclass::Method(int age){
printf ("%p %d\n",this,ahe );;
}
//转化C
void C++InputC (Myclass *this ,int age ){
printf ("%p %d\n",this,ahe );;
}
//C++调用,
Method(10);
//C调用
struct Myclass cls;
C++InputC(&cls,10);
//OC 转化 C
void OCInputC (struct MyObject *self,SEL _sel,int age);
通过Clang 编译C ++文件,入口
int main() {
//调用函数
void (*blk)(void) =
((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
//这样写
struct __main_block_desc_0 tmp =
((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));//block 语法就是这样的
// 结构体 = 结构体 (函数,开辟空间)block 语法就是这样的 ,就想alloc init 一样!
//赋值
struct __main_block_desc_0 *blk = &tmp ;
/*1.这句的意思就是 把源代码__main_blockdesc_0 结构体在生成的结构体实力的指针赋值给__main_block_desc_0
2.相当于
void (^blk)(void) = ^{
printf("block\n");
};
将block语法生成的block赋值类型变量blk。他等同于将 __main_blockdesc_0结构体实力的指针赋值给变量blk.改源码中的block就是__main_blockdesc_0结构体类型的自动变量,在栈上生成的__main_blockdesc_0结构体的实力
*/
((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
//这样写
(*blk->impl.FuncPtr)(blk);
//结构体指针 ,指向结构体指针
//blk 是一个函数指针可以指向函数地址,指向impl结构体地址,变量 funcptr就是一个__main_block_func_0就是打印函数
/*
//这就是简单地使用函数指针调用函数,
正如我们刚才所确认的,由block语法转化的__main_block_func_0函数的指针被赋值的成员变量funcptr中,另外也说明了,__main_block_func_0 函数的擦拭是指向block值的。在调用该函数的源码中可以看出block是作为参数传递的。
*/
return 1;
}
**结构体定义
struct __main_block_impl_0 {
struct __block_impl impl;//结构体变量
struct __main_block_desc_0* Desc;//Desc指针
//结构体构造函数,类似void OCInputC (struct MyObject *self,SEL _sel,int age);
__main_block_impl_0(void *fp,//数由block语法转化的c御寒函数指针。
struct __main_block_desc_0 *desc//__main_block_desc_0 实例化后的指针
, int flags=0) {
impl.isa = &_NSConcreteStackBlock;//用于初始化结构体的Isa成员的
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc; = &__main_block_desc_0_DATA
}
//结构体解析
void *isa; =&_NSConcreteStackBlock
int Flags; = = 0
int Reserved; = 0
void *FuncPtr; =__main_block_func_0
Desc = desc; = &__main_block_desc_0_DATA
};
struct __block_impl {
void *isa; =&_NSConcreteStackBlock
int Flags; = = 0
int Reserved; = 0
void *FuncPtr; =__main_block_func_0
};
//__maninBlock 结构体变量
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size;
}
//实例化代码 ,开辟空间size_t大小
__main_block_desc_0_DATA = {
0, sizeof(struct __main_block_impl_0)
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
printf("block\n");
}