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

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




1
#import 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 --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变量是受外界影响的,导致输出结果为空。

 

转载于:https://www.cnblogs.com/henusyj-1314/p/8589365.html

你可能感兴趣的:(iOS中block 静态全局局部变量block变量,以及对象,详解!)