block面试题

来源:互联网 发布:android编程语言 编辑:程序博客网 时间:2024/06/06 02:01

void testBlock()

{

    int a =100;

// __block int a = 100;


    NSLog(@"block定义前: %p", &a);//局部变量在栈区


    //在定义block的时候,如果引用到外部变量,在block中,会对外部变量建立一个副本(copy

    void (^myBlock)() = ^{

//     a = 90; //默认的情况下,block块中不允许修改外部变量的值。如果非要修改,外部变量定义前面加上修饰符__block

        NSLog(@"%d", a );

        NSLog(@"block定义中:%p", &a);//定义block后,a会在堆中建立一个副本

    };

    

    NSLog(@"block定义后:%p", &a);//栈区

    

    a = 80;

    

    myBlock();

}


输出Block里面的打印结果:

 block定义前: 0x7fff5fbff82c

 block定义后:0x7fff5fbff82c

 block定义中:100

 block定义中:0x100300020

根据打印结果可以知道:block是一组预先准备好的代码,在需要的时候myBlock()调用的时候)才被执行。

对于打印结果,为什么是100,直接看内存地址,就可以得到结果,block中的内存地址和外面的不是一块内存地址,因此也就无法改变block中的变量的值。

============================================================

void testBlock2()

{

    __blockint a  =100;

    NSLog(@"block定义前: %p", &a);//局部变量在栈区

    

    void (^myBlock)() = ^{

        NSLog(@"block定义中:%d", a );

        NSLog(@"block定义中:%p", &a);//定义block后,a会在堆中建立一个副本

    };

    

    NSLog(@"block定义后:%p", &a);//定义block后,a会在堆中建立一个副本

    

    a = 80;

    myBlock();

}

 Block[13195:1241198] block定义前: 0x7fff5fbff828

 Block[13195:1241198] block定义后:0x100400048

 Block[13195:1241198] block定义中:80

 Block[13195:1241198] block定义中:0x100400048


根据地址可以看到,为什么__block 修饰的变量可以在block中可以被修改地址了吧。

==========================

void testBlock3()

{

    NSMutableString *str = [NSMutableStringstringWithString:@"jdk"];

    NSLog(@"指向堆中字符串的地址:%p栈区变量的地址:%p", str, &str);

    void (^myBlock)() = ^{

        [str setString:@"LISA"];

         NSLog(@"m: %p %p %@", str, &str, str);

    };

    NSLog(@"af: %p %p", str, &str);

    myBlock();

}


Block[13330:1263164] 指向堆中字符串的地址:0x100106670栈区变量的地址:0x7fff5fbff828

2015-07-08 21:48:56.188 Block[13330:1263164] af: 0x100106670 0x7fff5fbff828

2015-07-08 21:48:56.188 Block[13330:1263164] m: 0x100106670 0x100200160 LISA


0 0
原创粉丝点击