zoukankan      html  css  js  c++  java
  • block 解析

    静态变量

    上一篇 我们了解了block全局变量的使用,静态变量和全局变量一样,可以直接在block内部使用,也可以在block内部修改

    引用官方文档:

    Global variables are accessible, including static variables that exist within the enclosing lexical scope.

    我们来看一段代码:

    声明一个静态变量,在block内部修改

    static NSString * _para1;
    -(void )test4
    {
        _para1=@"para1";
        //初始值
        NSLog(@"init para1:%@,%p,%p",_para1,&_para1,_para1);
        void (^myBlock)(int) = ^(int num) {
            //block内赋值
            _para1=@"para3";
            NSLog(@"excuteing para1:%@,%p,%p",_para1,&_para1,_para1);
        };
        //修改前赋值
        _para1=@"para2";
        NSLog(@"excutebefore para1:%@,%p,%p",_para1,&_para1,_para1);
        myBlock(1);
        //block执行后
        NSLog(@"excuteafter para1:%@,%p,%p",_para1,&_para1,_para1);
    }

    输出:

    2014-07-28 17:05:47.701 Test[2307:60b] init para1:para1,0x39bb0,0x399e4
    2014-07-28 17:05:47.704 Test[2307:60b] excutebefore para1:para2,0x39bb0,0x39a24
    2014-07-28 17:05:47.705 Test[2307:60b] excuteing para1:para3,0x39bb0,0x39a04
    2014-07-28 17:05:47.706 Test[2307:60b] excuteafter para1:para3,0x39bb0,0x39a04

    从日志可以看出,block里变量地址和外部的是一样的,而且可以修改静态变量。

    我们看一下转换后的代码:

    static NSString * _para1;
    
    struct __KDBlockTest__test4_block_impl_0 {
      struct __block_impl impl;
      struct __KDBlockTest__test4_block_desc_0* Desc;
      __KDBlockTest__test4_block_impl_0(void *fp, struct __KDBlockTest__test4_block_desc_0 *desc, int flags=0) {
        impl.isa = &_NSConcreteStackBlock;
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
      }
    };

    因为静态对象存在静态区(全局区)从创建到程序销毁一直存在,block内部没有声明对应的成员。下面是我们的test4 函数:

    static void _I_KDBlockTest_test4(KDBlockTest * self, SEL _cmd) {
        _para1=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_1;
    
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_2,_para1,&_para1,_para1);
        void (*myBlock)(int) = (void (*)(int))&__KDBlockTest__test4_block_impl_0((void *)__KDBlockTest__test4_block_func_0, &__KDBlockTest__test4_block_desc_0_DATA);
    
        _para1=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_5;
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_6,_para1,&_para1,_para1);
        ((void (*)(__block_impl *, int))((__block_impl *)myBlock)->FuncPtr)((__block_impl *)myBlock, 1);
    
        NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_7,_para1,&_para1,_para1);
    }

    block初始化,传入实现函数的指针和描述函数,并没有其他参数。

    void (*myBlock)(int) = (void (*)(int))&__KDBlockTest__test4_block_impl_0((void *)__KDBlockTest__test4_block_func_0, &__KDBlockTest__test4_block_desc_0_DATA);

    我们来看下实现的函数,直接引用了静态变量

    static void __KDBlockTest__test4_block_func_0(struct __KDBlockTest__test4_block_impl_0 *__cself, int num) {
    
    
            _para1=(NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_3;
            NSLog((NSString *)&__NSConstantStringImpl__var_folders_5l_2l25j3tn0wl_3zy1hpsq1rhc0000gp_T_KDBlockTest_3979e1_mi_4,_para1,&_para1,_para1);
        }

    不考虑循环引用的基础上,静态变量和成员变量使用上方法大致一样,但是原理上还是有区别的。

  • 相关阅读:
    .net core之上传文件的限制
    如何Telnet端口
    ES坑之logstash配置文件
    MySQL报错packets larger than max_allowed_packet are not allowed
    ES坑之安装
    ES坑之概述
    Git
    IDEA 搭建 maven(下)
    IDEA搭建maven(上)
    JDBC
  • 原文地址:https://www.cnblogs.com/NarutoYq/p/3873686.html
Copyright © 2011-2022 走看看