ios中Block内访问函数局部变量时变量的改变情况

来源:互联网 发布:软件 产品售后承诺书 编辑:程序博客网 时间:2024/05/18 01:09

int (^bk)(int);


void f1(void)

{

    int a=1//在栈区

    static int b=2//在数据区

    __blockint c=3;    //在栈区,由__block修饰的局部变量会在block代码中复制一份,但这个备份不在常量区,在数据区或堆区

    

    printf("f1&a=%p\n",&a); //f1&a=0x7fff5fbff84c

    printf("f1&b=%p\n",&b);   //f1&b=0x1000010d8

    printf("f1&c=%p\n",&c); //f1&c=0x7fff5fbff840

    printf("\n");

    

    bk=^(int x)

    {

        //代码块将a的值复制了一份放到了栈外,所以代码块真正访问的只是一个a的备份

        printf("bka=%d\n",a);

        printf("bk&a=%p\n",&a); //bk&a=0x100104df8

        printf("bkb=%d\n",b);   //bkb=2

        

        //c也不在栈上

        printf("bk&c=%p\n",&c); //bk&c=0x100103da8

        

        c=88;

        printf("&c=%d\n",c);   //&c=88

        

       // a=99;//此处不能修改a的值,因为a备份在代码区或常量区

        

        b=33;

        printf("block中修改b值后,b=%d  &b=%p\n",b,&b);//b=33

        

        return 0;

    };

}


//Bstatic修饰的变量,在block中可以使用,无地址复制还是原来的地址,无特殊。

//A普通声明的变量,原来在栈区,在block中应用,相当于复制了一份地址在栈外的区域,代码块真正访问的是a的一个备份,在block内部不可以修改,因为a在代码区或常量区

//C__block声明,开始声明时也在栈区,在block中应用时,会在block的代码块中复制一份,这块地址不在栈区,在数据区或堆区,在block中可以改变C的值,



void f2(void)

{

    __block int c=30;//在栈区

    printf("f2中,c=%d,&c=%p\n",c,&c);//f2中,c=30,&c=0x7fff5fbff848

    

    int(^bk)(int)=^(int x)

    {

        c=31;

        printf("f2中在bk,c=%d,&c=%p\n",c,&c);//f2中在bk,c=31,&c=0x100602bc8

        return 0;

    };

    //此处访问的cbk中的c,因为用__block修饰的函数局部变量的本意是让程序跟踪c变量在block中的变化而变化(或者直接使用block中的c)

    printf("f2中,调bk之前,c=%d,&c=%p\n",c,&c);//f2中,调bk之前,c=30,&c=0x100602bc8

    

    bk(1);

    

    printf("f2中,调bk之后,c=%d,&c=%p\n",c,&c);//f2中,调bk之后,c=31,&c=0x100602bc8

}


//__block声明的变量,本意是让程序跟踪c变量在block中的变化而变化,即使block还没有执行,但是变量C的地址已经改变了。但是C的值没有改变,当block执行完以后,C的值会发生改变,地址和block内部的地址是同一个地址,不在栈区。


#import <Foundation/Foundation.h>


int main(int argc, const char * argv[]) {

    @autoreleasepool {

    

        f1();

        bk(4);

        

        f2();

//        f1&a=0x7fff5fbff84c

//        f1&b=0x1000020d8

//        f1&c=0x7fff5fbff840

//        

//        bka=1

//        bk&a=0x1006029e8

//        bkb=2

//        bk&c=0x100602068

//        &c=88

//        block中修改b值后,b=33  &b=0x1000020d8

//        f2中,c=30,&c=0x7fff5fbff848

//        f2中,调bk之前,c=30,&c=0x100602bc8

//        f2中在bk,c=31,&c=0x100602bc8

//        f2中,调bk之后,c=31,&c=0x100602bc8

        

    }

    return 0;

}

0 0
原创粉丝点击