傻瓜学编程之block_2
block的实质
以一个简单的实现为列子;
- (void)myBlcokTest{
void (^blk)()=^{
printf(@“beijinghuanyingni”);
};
blk();
}
终端:clang -rewrite-objc 类文件名.m
cpp文件中关键代码:
static void _I_People_myBlcokTest(People * self, SEL _cmd) {
void (*blk)()=((void (*)())&__People__myBlcokTest_block_impl_0((void *)__People__myBlcokTest_block_func_0, &__People__myBlcokTest_block_desc_0_DATA));
((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk); } static void __People__myBlcokTest_block_func_0(struct __People__myBlcokTest_block_impl_0 *__cself) {
printf("woshinidexiaodaye");
} struct __People__myBlcokTest_block_impl_0 {
struct __block_impl impl;
struct __People__myBlcokTest_block_desc_0* Desc;
__People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
}; // 第一个成员
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
// 第二个成员
static struct __People__myBlcokTest_block_desc_0 {
size_t reserved;// 升级版本所需要的区域
size_t Block_size;//block大小
} __People__myBlcokTest_block_desc_0_DATA = { 0, sizeof(struct __People__myBlcokTest_block_impl_0)};
运行时的myBlcokTest方法;
static void _I_People_myBlcokTest(People * self, SEL _cmd) { void (*blk)()=((void (*)())&__People__myBlcokTest_block_impl_0((void *)__People__myBlcokTest_block_func_0, &__People__myBlcokTest_block_desc_0_DATA)); ((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk); }
去掉类型转化
static void _I_People_myBlcokTest(People * self, SEL _cmd) {
__People__myBlcokTest_block_impl_0 blk = __People__myBlcokTest_block_impl_0( __People__myBlcokTest_block_func_0, &__People__myBlcokTest_block_desc_0_DATA)); 、、、
}
__People__myBlcokTest_block_impl_0:是一个结构体 包含两个成员:
struct __block_impl impl;
struct __People__myBlcokTest_block_desc_0* Desc; 以及一个构造函数:
__People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0)
struct __People__myBlcokTest_block_impl_0 {
成员一: struct __block_impl impl; // __block_impl结构体
struct __block_impl {
void *isa;
int Flags;
int Reserved;
void *FuncPtr;
};
成员二: struct __People__myBlcokTest_block_desc_0* Desc;//__People__myBlcokTest_block_desc_0结构体
static struct __People__myBlcokTest_block_desc_0 {
size_t reserved;// 升级版本所需要的区域
size_t Block_size;//block大小
}
构造函数:
构造函数中成员的处理 在后面 构造函数中参数的处理部分解释;
__People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0)
{
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
};
通过结构体的构造函数生成一个block实例
__People__myBlcokTest_block_impl_0 blk = __People__myBlcokTest_block_impl_0( __People__myBlcokTest_block_func_0,
&__People__myBlcokTest_block_desc_0_DATA)); 构造函数参数的意义:
参数一: __People__myBlcokTest_block_func_0 //函数实现地址 在把函数赋值给函数指针的时候可以省略&;
在构造函数参数的意义: 把函数的地址赋值给指针 void *fp
函数的具体实现代码:
static void __People__myBlcokTest_block_func_0(struct __People__myBlcokTest_block_impl_0 *__cself) {
printf("woshinidexiaodaye");
}
这里面的__cself是什么后面会解释;
参数二: &__People__myBlcokTest_block_desc_0_DATA // __People__myBlcokTest_block_desc_0的默认初始化
{ 0, sizeof(struct __People__myBlcokTest_block_impl_0) //使用__People__myBlcokTest_block_impl_0的大小进行初始化
具体代码:
static struct __People__myBlcokTest_block_desc_0 {
size_t reserved;// 升级版本所需要的区域
size_t Block_size;//block大小
} __People__myBlcokTest_block_desc_0_DATA = { 0, sizeof(struct __People__myBlcokTest_block_impl_0)};
函数指针 与指针函数点击这里
构造函数中参数的处理
__People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0)
{
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
}
赋值之后:
__People__myBlcokTest_block_impl_0(void *fp, struct __People__myBlcokTest_block_desc_0 *desc, int flags=0)
{
impl.isa = &_NSConcreteStackBlock;//_NSConcreteStackBlock用于初始化isa成员 后面具体解释
impl.Flags = 0;
impl.FuncPtr =__People__myBlcokTest_block_func_0;
imlp.Reserved=0;
Desc =__People__myBlcokTest_block_desc_0_DATA;
}
再来看看block的调用:
blk();
((void (*)(__block_impl *))((__block_impl *)blk)->FuncPtr)((__block_impl *)blk);
简化
((__block_impl *)blk)->FuncPtr)((__block_impl *)blk); =>(blk ->FuncPtr)(blk)
获取blk结构体中函数指针FuncPtr 通过该函数指针调用函数 并且参数值为blk 点击这里;
这个等价于
(blk ->FuncPtr)(blk) 相当于
blk -> __People__myBlcokTest_block_func_0(blk);
再看看
static void __People__myBlcokTest_block_func_0(struct __People__myBlcokTest_block_impl_0 *__cself) {
printf("woshinidexiaodaye");
}
说明 __cself 就是blk 本身;
傻瓜学编程之block_2的更多相关文章
- 傻瓜学编程之block_3
block 捕获自动变量的瞬间值: 注释在代码中:请参考傻瓜学编程之block_3 import "People.h" @interface People() { int your ...
- 傻瓜学编程之block_1
1.引出 1.1.int pp = 3;for循环为dd赋值并 调用 finprint(int ,int)函数 获取pp*dd的乘积,输出 void finalValue(int d, int sca ...
- C#可扩展编程之MEF学习笔记(五):MEF高级进阶
好久没有写博客了,今天抽空继续写MEF系列的文章.有园友提出这种系列的文章要做个目录,看起来方便,所以就抽空做了一个,放到每篇文章的最后. 前面四篇讲了MEF的基础知识,学完了前四篇,MEF中比较常用 ...
- 2017“编程之美”终章:AI之战勇者为王
编者按:8月15日,第六届微软“编程之美”挑战赛在选手的火热比拼中圆满落下帷幕.“编程之美”挑战赛是由微软主办,面向高校学生开展的大型编程比赛.自2012年起,微软每年都在革新比赛命题.紧跟时代潮流, ...
- 网络编程之TCP/IP各层详解
网络编程之TCP/IP各层详解 我们将应用层,表示层,会话层并作应用层,从TCP/IP五层协议的角度来阐述每层的由来与功能,搞清楚了每层的主要协议,就理解了整个物联网通信的原理. 首先,用户感知到的只 ...
- Python Flask高级编程之RESTFul API前后端分离精讲 (网盘免费分享)
Python Flask高级编程之RESTFul API前后端分离精讲 (免费分享) 点击链接或搜索QQ号直接加群获取其它资料: 链接:https://pan.baidu.com/s/12eKrJK ...
- Python网络编程之TCP套接字简单用法示例
Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...
- Python Flask高级编程之从0到1开发《鱼书》精品项目
Python Flask高级编程之从0到1开发<鱼书>精品项目 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感 ...
- Java并发编程之CAS二源码追根溯源
Java并发编程之CAS二源码追根溯源 在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理. 本篇是<凯哥(凯哥Java: ...
随机推荐
- Flyweight 享元(结构型)
一:描述:(该模式实际应用较少) Flyweight 享元模式是对大量细粒度的元素进行共享和重用.减少对象的创建减轻内存: 注和单例模式不同的是:享元模式的各个对象佣有各自的行为并可实例化,单例模式的 ...
- jQuery图片自动添加水印插件
JS脚本(jQuery)为图片加水印效果预览:http://hovertree.com/texiao/jquery/94/ 本功能使用HTML5实现,可为图片加上文字水印,可设置文字,设置颜色,位置等 ...
- string 迭代器
#include <iostream>#include <string>#include<algorithm>#define m 10000000using nam ...
- Request、Response
Request Request对象在我们写爬虫发送请求的时候调用,参数如下: url: 就是需要请求的url callback: 指定该请求返回的Response由那个函数来处理. method: 请 ...
- python3-datetime.date详解(一)
datetime是python操作日期和时间的内置模块. python有两种日期.时间对象:“naive”和“aware”.前者由于忽略了实际情况更容易理解,操作.在任何时间空间内,它的值都取决于一个 ...
- SQL语句删除和添加外键、主键的方法
--删除外键 语法:alter table 表名 drop constraint 外键约束名 如: alter table Stu_PkFk_Sc drop constraint FK_s alter ...
- PTA8
这个作业属于哪个课程 C语言程序设计2 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/software-engineering-class2-2018/ ...
- 数据库关闭,shutdown三种语句。
1.shutdown normal 正常方式关闭数据库. 2.shutdown immediate 立即方式关闭数据库. 在SVRMGRL中执行shutdown immedia ...
- annotation的理解
Annotations提供一些本来不属于程序的数据. 比如:一段代码的作者或者告诉编译器禁止一些特殊的错误.An annotation 对代码的执行没有什么影响.Annotations使用@annot ...
- 关于定时器setTimeout()方法的实践--巧解bug
_使用开发环境:UAP:_ _框架:JQuery.MX:_ 最近的开发的页面中,有一处需要在提交的 datagrid里启用行编辑,就会发生奇怪的bug,编辑过程中如图所示不移开焦点直接点保存,那么已输 ...