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

原文地址:https://www.cnblogs.com/henusyj-1314/p/8589365.html

时间: 2024-12-12 03:31:05

iOS中block 静态全局局部变量block变量,以及对象,详解!的相关文章

ios中创建可以拖动的view原理和实现详解

有时候我们会需要在界面上拖动view;uiview是继承于uiresponder的,所以可以响应触摸相关的事件. 重点是以下一组方法: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesEnded:(NSSet *)touches withEvent:(UIE

ios中创建可以拖动的view原理和实现详解(含代码)

有时候我们会需要在界面上拖动view;uiview是继承于uiresponder的,所以可以响应触摸相关的事件. 重点是以下一组方法: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesEnded:(NSSet *)touches withEvent:(UIE

Linux中PATH、CLASSPATH等环境变量配置格式详解

代码格式详解 看几个例子, 1 #set java environment 2 export JAVA_HOME=/usr/lib/jvm/jdk1.7.0_79 3 export CLASSPATH=.:${JAVA_HOME}/lib/tools.jar:${JAVA_HOME}/lib/dt.jar 4 export PATH=$JAVA_HOME/bin:$PATH 5 6 #set hadoop environment 7 export HADOOP_HOME=/opt/hadoop-

iOS中 扫描二维码/生成二维码详解 韩俊强的博客

最近大家总是问我有没有关于二维码的demo,为了满足大家的需求,特此研究了一番,希望能帮到大家! 每日更新关注:http://weibo.com/hanjunqiang  新浪微博 指示根视图: self.window.rootViewController = [[UINavigationController alloc]initWithRootViewController:[SecondViewController new]]; 每日更新关注:http://weibo.com/hanjunqi

iOS中nil 、NULL、 Nil 、NSNull的详解(一)

1.nil >Defines the id of a null instance. 定义一个实例为空, 指向oc中对象的空指针. >示例代码: NSString *someString = nil; NSURL *someURL = nil; id someObject = nil; if (anotherObject == nil) // do something >当对某个对象release 的同时最好把他们赋值为nil,这样可以确保安全性,如果不赋值nil,可能导致程序崩溃.   

iOS中 视频直播功能-流媒体的使用(详解)韩俊强的CSDN博客

上一篇博客:(流媒体实现视频播放和下载功能):http://blog.csdn.net/qq_31810357/article/details/50574914 最近视频直播功能比较火,处于需求,研究了一番,根据分析决定使用流媒体实现,代码简单易懂,接下来看教程: 每日更新关注:http://weibo.com/hanjunqiang  新浪微博 简单介绍: HLS 协议 : >5M会被AppStore拒绝  服务器要求低   延迟高    多平台 RTMP 协议:  电视直播   PC端使用

java中静态代码块的用法 static用法详解

(一)java 静态代码块 静态方法区别一般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,这种代码是被动执行的. 静态方法在类加载的时候 就已经加载 可以用类名直接调用比如main方法就必须是静态的 这是程序入口两者的区别就是:静态代码块是自动执行的;静态方法是被调用的时候才执行的.静态方法(1)在Java里,可以定义一个不需要创建对象的方法,这种方法就是

&quot;静态方法里只能调用静态变量和静态方法&quot;详解

静态方法里可以调用静态方法和静态变量,同时也能调用非静态方法和非静态变量. public class Test { public Test() {}; public Test(int i) {this.n = i;} public static int m = 5; public int n = 10; public void fun1() {System.out.println("非静态方法fun1");} public static void fun2() {System.out.

iOS回顾笔记(04) -- UIScrollView的基本使用详解

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption