当前位置: 首页 > news >正文

取名字的网站 优帮云网站在建设中是什么意思

取名字的网站 优帮云,网站在建设中是什么意思,html怎么做移动端网站,wordpress获取用户文章block 文章目录block如何通过终端clang生成源码cpp文件block实质截获自动变量全局变量和静态变量的截获__block说明符iOS开发“强弱共舞”——weak和strong配套使用解决block循环引用问题如何通过终端clang生成源码cpp文件 之前在学习block中学习的比较浅#xff0c;只看了oc…block 文章目录block如何通过终端clang生成源码cpp文件block实质截获自动变量全局变量和静态变量的截获__block说明符iOS开发“强弱共舞”——weak和strong配套使用解决block循环引用问题如何通过终端clang生成源码cpp文件 之前在学习block中学习的比较浅只看了oc高级编程书上有的源码学习的比较浅这节来对之前的作以补充。 首先来看看怎么将oc文件生成cpp的源码文件 将项目大文件里的二级文件打开终端 cd 并将此文件拖入 然后再输入 clang -rewrite-objc main.m回车打开之前的项目文件即可看到生成了一个cpp文件打开就是oc的c源码。 打开后发现有60000多行很抽象关键部分看最前面和最后面即可。 block实质 我们现在时文件中写一个最简单的block看看源码是什么 int main(int argc, const char * argv[]) {autoreleasepool {// insert code here...void (^blk)(void) ^{printf(Block\n);};blk();}return 0; }源码 //经过clang转换后的C代码 struct __block_impl {void *isa;//指向所属类的指针int Flags;//标志性参数暂时没用到所以默认为0int Reserved;//今后版本升级所需的区域大小。void *FuncPtr;//函数指针指向实际执行的函数也就是block中花括号里面的代码内容。 };struct __main_block_impl_0 {struct __block_impl impl;//上面点1中的结构体的变量struct __main_block_desc_0* Desc;//上面点2中的结构体的指针 __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags0) {impl.isa _NSConcreteStackBlock;impl.Flags flags;impl.FuncPtr fp;Desc desc;} };static void __main_block_func_0(struct __main_block_impl_0 *__cself {printf(Block\n); }static struct __main_block_desc_0 {size_t reserved; //今后版本升级所需区域的大小一般填0size_t Block_size; //Block的大小 } __main_block_desc_0_DATA { 0, sizeof(struct __main_block_impl_0)};int main(int argc, const char * argv[]) {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);return 0; }我们来分开说一下每部分的意义 1.第一个结构体 struct __block_impl {void *isa;//指向所属类的指针int Flags;//标志性参数暂时没用到所以默认为0int Reserved;//今后版本升级所需的区域大小。void *FuncPtr;//函数指针指向实际执行的函数也就是block中花括号里面的代码内容。 };结构体的名称impl即implementation的缩写换句话说这一部分是block的实现部分结构体。void *isa声明一个不确定类型的指针用于保存Block结构体实例。int Flags标识符。int Reserved今后版本升级所需的区域大小。void *FuncPtr函数指针指向实际执行的函数也就是block中花括号里面的代码内容。 2.在介绍struct __main_block_impl_0结构体之前先介绍一下这个结构体里的static struct __main_block_desc_0结构体 这个结构体在上面一坨源码的最底下 static struct __main_block_desc_0 {size_t reserved; //今后版本升级所需区域的大小一般填0size_t Block_size; //Block的大小 } __main_block_desc_0_DATA { 0, sizeof(struct __main_block_impl_0)};第一个成员变量指的是今后版本升级所需区域的大小一般填0。第二个成员变量是Block的大小。 __main_block_desc_0_DATA { 0, sizeof(struct __main_block_impl_0)}; 1⃣️.这就是和我们平时用结构体一样在定义完最后写一个结构体实例变量变量名就是__main_block_desc_0_DATA。 2⃣️.其中reserved为0Block_size是sizeof(struct __main_block_impl_0)。 3.接下来看struct __main_block_impl_0结构体 struct __main_block_impl_0 {struct __block_impl impl;//上面点1中的结构体的变量struct __main_block_desc_0* Desc;//上面点2中的结构体的指针__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags0) {impl.isa _NSConcreteStackBlock;impl.Flags flags;impl.FuncPtr fp;Desc desc;} };第一个成员变量是impl也就是上面点1中的结构体的变量。第二个成员变量是Desc指针就是上面点2中的结构体的指针。剩下的代码是初始化含有这些结构体的__main_block_impl_0结构体的构造函数给结构体里的元素赋值。 4.然后是static void __main_block_func_0 static void __main_block_func_0(struct __main_block_impl_0 *__cself {printf(Block\n); }这个就比较简单了Blcok执行的实际代码块。也是点3中fp指针指向的函数。括号中的参数__cself是相当于OC语言版的self代表的是Block本身。 5.最后来看main函数 int main(int argc, const char * argv[]) {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);return 0; } 这两句代码不长但是比较恶心我们先来看第一句把强制类型转换去一下试试 //加了个临时变量temp看着更方便点 struct __main_block_impl_0 temp __main_block_impl_0(__main_block_func_0, __main_block_desc_0_DATA); struct __main_block_impl_0 *blk temp;该源代码将__main_block_impl_0结构体类型的自动变量也就是栈上生成的__main_block_impl_0结构体实例的指针赋值给__main_block_impl_0结构体指针类型的变量blk。 第二行代码就是相当于源代码中的blk()即使用该Block部分。去掉转换部分就是 (*blk-impl.FuncPtr)(blk);这是使用函数指针调用函数。由Block语法转换的__main_block_impl_0函数的指针被赋值成员变量FunPtr中。 截获自动变量 int main(int argc, const char * argv[]) {int dmy 256;int val 10;const char *fmt val %d\n;void (^blk)(void) ^{printf(fmt, val);};blk();return 0; }转化后的代码 //经过clang转换后的C代码 struct __block_impl {void *isa;int Flags;int Reserved;void *FuncPtr; };struct __main_block_impl_0 {struct __block_impl impl;struct __main_block_desc_0* Desc;const char *fmt;int val;__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, const char *_fmt, int _val, int flags0) : fmt(_fmt), val(_val) {impl.isa _NSConcreteStackBlock;impl.Flags flags;impl.FuncPtr fp;Desc desc;} };static void __main_block_func_0(struct __main_block_impl_0 *__cself {const char *fmt __cself-fmt;int val __cself-val; printf(fmt, val); }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)};int main(int argc, const char * argv[]) {int dmy 256;int val 10;const char *fmt val %d\n;void (*blk)(void) ((void (*)())__main_block_impl_0((void *)__main_block_func_0, __main_block_desc_0_DATA, fmt, val));return 0; }与上次不同的是在Block语法表达式中使用的自动变量被当作成员变量追加到了__main_block_impl_0结构体中 struct __main_block_impl_0 {struct __block_impl impl;struct __main_block_desc_0* Desc;const char *fmt;int val; }初始化该结构体实例的构造函数也发生了变化 __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, const char *_fmt, int _val, int flags0) : fmt(_fmt), val(_val) 初始化时自动变量fmt和val进行了赋值操作 impl.isa _NSConcreteStackBlock;impl.Flags flags;impl.FuncPtr fp;Desc desc;fmt val %d\n;val 10;在转换后的代码中截获到__main_block_impl_0结构体实例的成员变量上的自动变量这些变量在Block语法表达式之前被声明定义所以之后即使改变自动变量的值也不会对Block语法中的内容有所变化。 总的来说所谓“截获自动变量值”意味着在执行Block语法时Block语法表达式所使用的自动变量值被保存到Block的结构体实例即Block自身中。 总结一下就是说 调用__main_block_impl_0的构造函数构造函数正常有两个参数func_0和desc_0在截获自动变量时会把需要截获的自动变量也放入参数列表中同时__main_block_impl_0中也会增加两个成员变量a,b构造函数带参数就是自动给这两个成员变量赋值。在调用func_0时直接通过__cself相当于self其传递的参数也是其本身的a、b此时的a,b就是成员变量中的因为上面的构造函数已经赋值了 全局变量和静态变量的截获 我们以以下代码为例 int global_val 10; // 全局变量 static int static_global_val 20; // 静态全局变量int main(int argc, const char * argv[]) {autoreleasepool {static int static_val 30; // 静态局部变量void (^myLocalBlock)(void) ^{global_val * 1;static_global_val * 2;static_val * 3;printf(static_val %d, static_global_val %d, global_val %d\n,static_val, static_global_val, global_val);};myLocalBlock();}return 0; }源码 struct __block_impl {void *isa;int Flags;int Reserved;void *FuncPtr; };int global_val 10; static int static_global_val 20;struct __main_block_impl_0 {struct __block_impl impl;struct __main_block_desc_0* Desc;int *static_val;__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int *_static_val, int flags0) : static_val(_static_val) {impl.isa _NSConcreteStackBlock;impl.Flags flags;impl.FuncPtr fp;Desc desc;} }; static void __main_block_func_0(struct __main_block_impl_0 *__cself) {int *static_val __cself-static_val; // bound by copyglobal_val * 1;static_global_val * 2;(*static_val) * 3;printf(static_val %d, static_global_val %d, global_val %d\n,(*static_val), static_global_val, global_val);}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)}; int main(int argc, const char * argv[]) {/* autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; static int static_val 30;void (*myLocalBlock)(void) ((void (*)())__main_block_impl_0((void *)__main_block_func_0, __main_block_desc_0_DATA, static_val));((void (*)(__block_impl *))((__block_impl *)myLocalBlock)-FuncPtr)((__block_impl *)myLocalBlock);}return 0; }我们主要来看下这段代码 static void __main_block_func_0(struct __main_block_impl_0 *__cself) {int *static_val __cself-static_val; // bound by copyglobal_val * 1;static_global_val * 2;(*static_val) * 3;printf(static_val %d, static_global_val %d, global_val %d\n,(*static_val), static_global_val, global_val);}我们发现只有static_val是从__cself中获取的值 再来看看上面的一段代码 struct __main_block_impl_0 {struct __block_impl impl;struct __main_block_desc_0* Desc;int *static_val;__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int *_static_val, int flags0) : static_val(_static_val) {impl.isa _NSConcreteStackBlock;impl.Flags flags;impl.FuncPtr fp;Desc desc;} };我们发现全局变量静态全局变量我们的Block都没有用结构体去特地保存它只有对于我们的静态局部变量会来保存但这里要注意我们使用的不是int static_val而是int *static_val也就是说我们使用一个指针来保存的静态局部变量它会直接保存该变量的地址之后的操作也是直接对该值本身进行操作而不是向之前截获的那些变量等于是重新开辟空间进行保存 产生这个问题的原因 原因在于我们的静态变量是存在数据区的在程序结束前它其实一直都会存在之所以会被称为局部只是说出了作用域无法调用到它了并不是说这块数据不存在了。因此我们只要自己准备好一个指针保证出了作用域依然能调用到他就行而对于自动变量它们真正的问题在于一但出了作用域直接被释放了所以要在结构体里开辟空间重新存放进行值传递 __block说明符 来看书上的例子 int main(int argc, const char * argv[]) {__block int val 10;void (^blk)(void) ^{val 1;printf(val %d\n, val);};blk();return 0; }转换后的源码 struct __Block_byref_val_0 {void *__isa;__Block_byref_val_0 *__forwarding;int __flags;int __size;int val; };struct __main_block_impl_0 {struct __block_impl impl;struct __main_block_desc_0* Desc;__Block_byref_val_0 *val; // by ref__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, __Block_byref_val_0 *_val, int flags0) : val(_val-__forwarding) {impl.isa _NSConcreteStackBlock;impl.Flags flags;impl.FuncPtr fp;Desc desc;} };static void __main_block_func_0(struct __main_block_impl_0 *__cself) {__Block_byref_val_0 *val __cself-val; (val-__forwarding-val) 1;printf(val %d\n, (val-__forwarding-val)); }static void __main_block_copy_0(struct __main_block_impl_0*dst, struct __main_block_impl_0*src) {_Block_object_assign((void*)dst-val, (void*)src-val, BLOCK_FIELD_IS_BYREF); }static void __main_block_dispose_0(struct __main_block_impl_0*src {_Block_object_dispose((void*)src-val, BLOCK_FIELD_IS_BYREF); }static struct __main_block_desc_0 {size_t reserved;size_t Block_size;void (*copy)(struct __main_block_impl_0*, struct __main_block_impl_0*);void (*dispose)(struct __main_block_impl_0*); } __main_block_desc_0_DATA { 0, sizeof(struct __main_block_impl_0), __main_block_copy_0, __main_block_dispose_0 };int main(int argc, const char * argv[]) {__Block_byref_val_0 val {0,(__Block_byref_val_0 *)val, 0, sizeof(__Block_byref_val_0), 10};blk __main_block_impl_0(__main_block_func_0, __main_block_desc_0_DATA, val, 0x22000000);return 0; }和没加修饰符的比较来说主要有两处不同 struct __Block_byref_val_0 {void *__isa;__Block_byref_val_0 *__forwarding;int __flags;int __size;int val; }; 在第一个结构体中我们发现多了一个__Block_byref_val_0 *__forwarding这个相当于指向该结构体本身的一个指针。 第二个地方 static void __main_block_func_0(struct __main_block_impl_0 *__cself) {__Block_byref_val_0 *val __cself-val; (val-__forwarding-val) 1;printf(val %d\n, (val-__forwarding-val)); }在这里我们发现打印的并不是__Block_byref_val_0 *val而是(val-__forwarding-val)。 最后来看一下主函数 int main(int argc, const char * argv[]) {__Block_byref_val_0 val {0,(__Block_byref_val_0 *)val, 0, sizeof(__Block_byref_val_0), 10};blk __main_block_impl_0(__main_block_func_0, __main_block_desc_0_DATA, val, 0x22000000);return 0; }看下其中赋值部分 __Block_byref_val_0 val {0,(__Block_byref_val_0 *)val, 0, sizeof(__Block_byref_val_0), 10};这个__block变量val变为了__Block_byref_val_0结构体变量。通过调用 static void __main_block_func_0函数通过__Block_byref_val_0结构体成员变量__forwarding访问成员变量val将10赋给val。 iOS开发“强弱共舞”——weak和strong配套使用解决block循环引用问题 __weak是为了解决循环引用 如果一个对象A持有了一个block同时block内又持有了对象A为了解决循环引用我们要在用__weak修饰完对象A后再去持有它这样就解决了循环引用。 __strong可以防止block持有的对象提前释放 我们用GCD延迟方法打印self的信息 - (void)touchesBegan:(NSSetUITouch * *)touches withEvent:(UIEvent *)event{[self dismissViewControllerAnimated:YES completion:nil];__weak typeof(self) weakSelf self;void (^Block) (void) ^{dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{NSLog(%, weakSelf);});};Block(); }输出结果 点击屏幕当前控制器消失同时被销毁掉5秒后打印的weakSelf就是一个(null)而我们如果在block内使用__strong后就能保证再打印完strongSelf之后再释放当前控制器。 - (void)touchesBegan:(NSSetUITouch * *)touches withEvent:(UIEvent *)event{[self dismissViewControllerAnimated:YES completion:nil];__weak typeof(self) weakSelf self;void (^Block) (void) ^{__strong typeof(self) strongSelf weakSelf;dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{NSLog(%, strongSelf);});};Block(); }
http://www.w-s-a.com/news/33653/

相关文章:

  • 网站充值提现公司账务怎么做中国能建设计公司网站
  • 网站信息资源建设包括哪些网站网站做维护
  • 网站性能优化的方法有哪些建设施工合同网站
  • 郑州建设企业网站山西省住房和城乡建设厅网站
  • 做网站的去哪找客户正规制作网站公司
  • 网站代理访问是什么意思外国优秀设计网站
  • 合肥个人建站模板网络技术服务有限公司
  • 做网站什么公司好dw企业网站开发教程
  • 怎么做自己的个人网站宝安网站设计哪家最好
  • 浩博建设集团网站站长网站统计
  • 电商网站开发视频seo排名优化方式方法
  • 宿迁市住房城乡建设局网站wordpress纯图片主题
  • 广州建设网站 公司湖北省建设信息网官网
  • 网站建立时间查询做百度移动网站优化排
  • 网站建设和运行费用qq恢复官方网站
  • 可以免费建立网站吗免费的网络营销方式
  • 天津企业设计网站建设wordpress标题字体大小
  • 上高县城乡规划建设局网站创业项目
  • 钓鱼网站在线下载广州网站设计哪里好
  • 做阿里国际网站会有成效吗wordpress微博同步
  • 西安网站建设云速网络网站运营情况怎么写
  • 免费建网站的网站微信商城分销系统方案
  • 烟台网站seo服务友情链接有哪些展现形式
  • 什么是移动网站开发免费网站开发框架
  • 做网站 创业wordpress子菜单
  • 门户网站类型有哪些权重7以上的网站
  • 政务网站建设论文android app开发教程
  • 网站开发实训h5总结个人网站注册平台要多少钱
  • 空白网站建设wordpress高亮代码过长
  • 盐城 网站开发什么叫做门户网站