• iOS中block 静态全局局部变量block变量,以及对象,详解!


    //最近总是犯迷糊,关于block对外部变量的引用,今天有时间就写了一下,加深自己的理解,巩固基础知识




    1
    #import <Foundation/Foundation.h> 2 int gNum = 100; 3 int main(int argc, const char * argv[]) { 4 @autoreleasepool { 5 static int sNum = 100; 6 __block int bNum = 100; 7 int lNum = 100; 8 int (^sum)(int, int) = ^(int a, int b) { 9 NSLog(@"%d %d %d %d",sNum,gNum,lNum,bNum); 10 sNum++; 11 bNum++; 12 gNum++; 13 return a + b + lNum + gNum + sNum + bNum ; 14 }; 15 sNum = 1; 16 bNum = 1; 17 gNum = 1; 18 lNum = 1; 19 20 NSLog(@"%d",sum(1,2)); 21 NSLog(@"%d",sNum); 22 NSLog(@"%d",bNum); 23 NSLog(@"%d",gNum); 24 NSLog(@"%d",lNum); 25 26 } 27 return 0; 28 }




    打印结果

    1 12:57:09.984 xxx[10180:2208151] 109
    2 12:57:09.984 xxx[10180:2208151] 2
    3 12:57:09.984 xxx[10180:2208151] 2
    4 12:57:09.984 xxx[10180:2208151] 2
    5 12:57:09.984 xxx[10180:2208151] 1

    Block其实包含两个部分内容 
    1.Block执行的代码,这是在编译的时候已经生成好的; 
    2.一个包含Block执行时需要的所有变量值的数据结构。Block将使用到的,作用域附近的变量的值建立一份快照拷贝到栈上。 
    Block与函数另一个不同是,Block类似Objc的对象,可以使用自动释放池管理内存 
    3 Block对外部变量的存取管理 
    基本数据类型 
    1,局部变量 
    局部自动变量,在Block中只读。Block定义时copy变量的值,在Block中作为常量使用,所以即使变量的值在Block外改变,也不影响他在Block中的值。 
    2, static修饰符的静态变量或全局变量 
    因为全局变量货静态变量在内存中的地址是固定的,Block在读取改变量值的时候是直接从其所在的内存读出的,获取daode 是最新值,而不是在定义时copy的常量。 
    3,__block修饰的变量 
    block变量,在被__block修饰的变量称作Block变量。基本类型的Block变量等小雨全局变量或静态变量。Block的使用很像函数指针,不过与函数最大的不同是:Block可以访问函数以外,词法作用域以内的外部变量的值。

    二、对象类型

    //本地对象

    - (void)localObjTest  
    {  
        UILabel *localObj = [[UILabel alloc]init];  
        NSLog(@"localObj adress --%p", & localObj);  
        void (^test)() = ^{  
            NSLog(@"localObj adress --%p", & localObj);  
            NSLog(@"localObj --%@",localObj);  
        };  
        localObj = nil;  
        test();  
    }  

    打印结果:

    2018-03-17 13:44:25.848 test1[1332:79267] localObj adress-- 0xbff7ced4
    
    
    2018-03-17 13:44:25.848 test1[1332:79267] localObj adress-- 0x7b63f8b4
    
    
    2018-03-17 13:44:25.848 test1[1332:79267] localObj --<UILabel: 0x7c8337a0; frame = (0 0; 0 0);

     

    //静态对象  
    - (void)staticObjTest  
    {  
        static UILabel *staticObj ;  
        staticObj = [[UILabel alloc]init];  
        NSLog(@"staticObj adress --%p", & staticObj);  
        void (^test)() = ^{  
            NSLog(@"staticObj adress --%p", & staticObj);  
            NSLog(@"staticObj --%@",staticObj);  
        };  
        staticObj = nil;  
        test();  
    }  
    
     

    打印结果:

    2018-03-17 13:44:25.917 test1[1332:79267] staticObjadress -- 0x85a48
    
    
    2018-03-17 13:44:25.917 test1[1332:79267] staticObjadress -- 0x85a48
    
    
    2018-03-17 13:44:25.917 test1[1332:79267] staticObj --(null)

     

    //全局对象  
    - (void)globalObjTest  
    {  
        globalObj = [[UILabel alloc]init];  
        NSLog(@"staticObj adress --%p", & globalObj);  
        void (^test)() = ^{  
            NSLog(@"globalObj adress --%p", & globalObj);  
            NSLog(@"globalObj --%@",globalObj);  
        };  
        globalObj = nil;  
        test();  
    }  
    打印结果:
    2018-03-17 13:44:25.917 test1[1332:79267] staticObjadress -- 0x85a4c
    
    
    2018-03-17 13:44:25.917 test1[1332:79267] globalObjadress -- 0x85a4c
    
    
    2018-03-17 13:44:25.917 test1[1332:79267] globalObj --(null)

     

    //block对象  
    - (void)blockObjTest  
    {  
        __block UILabel *blockObj = [[UILabel alloc]init];  
        NSLog(@"blockObj adress --%p", & blockObj);  
        void (^test)() = ^{  
            NSLog(@"blockObj adress --%p", & blockObj);  
            NSLog(@"blockObj --%@",blockObj);  
        };  
        blockObj = nil;  
        test();  
    }  

    打印结果:

    2018-03-17 13:44:25.917 test1[1332:79267] blockObj adress-- 0xbff7ced0
    
    
    2018-03-17 13:44:25.918 test1[1332:79267] blockObj adress-- 0x7c835598
    
    
    2018-03-17 13:44:25.918 test1[1332:79267] blockObj --(null)

    总结:从测试结果可以看到

    *对于静态对象变量和全局对象变量,其地址同样不是固定的。

    *对于局部(本地)对象变量,定义block的时候同样复制了(指针)变量,其在block中是作为(指针)常量使用的,不会受外界影响。

    *对于block对象变量,定义block的时候同样将变量从栈转移到了堆上,这一点用刚才的方法同样可以验证。因此block变量是受外界影响的,导致输出结果为空。

  • 相关阅读:
    iOS Core Animation 简明系列教程
    常用的iOS第三方资源
    超全!整理常用的iOS第三方资源
    iOS使用Workspace来管理多项目 ( 转 )
    转 与App Store审核的斗智斗勇
    Python -- Web -- WSGI
    Python -- Web
    Python -- 序列化
    Python -- 文档测试
    Python -- 单元测试
  • 原文地址:https://www.cnblogs.com/henusyj-1314/p/8589365.html
Copyright © 2020-2023  润新知