美文网首页
如何使用Block来修改外部变量

如何使用Block来修改外部变量

作者: 俊俊吖 | 来源:发表于2017-02-20 11:14 被阅读0次

    我们都知道:block 是不允许修改外部变量的,这里所说的外部变量的值,指得是栈中指针的内存地址。__Block 的作用是只要观察到该变量被被Block所持有,就将"外部变量"在栈中的内存地址放到了堆中。进而在Block内部也可以修改外部变量的值。

    1.例如:修改基本数据类型值中的Int 类型(浮点型一样的道理)

    -(void)testBlock{

    __block

    int a =0;

    NSLog(@"定义前:%p,a ===%d",&a,a);

    void(^foo)(NSString*name) = ^(NSString*str){

    a =1;

    NSLog(@"block内部,a ====%d :%p",a,&a);

    };

    foo(@"1111");

    NSLog(@"定以后:%p,a === %d",&a,a);

    }

    运行结果如下:

    NewCocoTest[1316:35458]定义前:0x7fff56bdc7b8,a ===0

    2017-02-20 10:12:16.867 NewCocoTest[1316:35458] block内部,a ====1 :0x600000033998

    2017-02-20 10:12:16.867 NewCocoTest[1316:35458]定以后:0x600000033998,a === 1

    加上__Block 以后就产生了浅拷贝,内存地址由原来的栈区,变成了堆区。

    2.修改基本数据类型中的char 类型

    例子:

    -(void)testBlockTwo{

    NSMutableString*a = [NSMutableStringstringWithFormat:@"Tom"];

    NSLog(@"定义以前a指向的堆中地址;%p,a在栈中的指针地址:%p,a ======%@",a,&a,a);

    void(^foo)(void) = ^{

    a.string=@"Jeery";

    NSLog(@"block内部a指向的堆中地址:%p,a在栈中的指针地址%p,a ======%@",a,&a,a);

    };

    foo();

    NSLog(@"Block以后a在堆中的地址%p,a在栈中的指针地址%p,a ======%@",a,&a,a);

    }

    运行结果如下:

    NewCocoTest[1316:35458]定义以前a指向的堆中地址;0x608000275e80,a在栈中的指针地址:0x7fff56bdc7b8,a ======Tom

    2017-02-20 10:12:16.868 NewCocoTest[1316:35458] block内部a指向的堆中地址:0x608000275e80,a在栈中的指针地址0x600000045f30,a ======Jeery

    2017-02-20 10:12:16.868 NewCocoTest[1316:35458] Block以后a在堆中的地址0x608000275e80,a在栈中的指针地址0x7fff56bdc7b8,a ======Jeery

    这里的a已经由基本数据类型,变成了对象类型。block会对对象类型的指针进行copy,copy到堆中,但并不会改变该指针所指向的堆中的地址,block体内修改的实际是a指向的队中的内容。

    总结:Block不允许修改外部变量的值,其实是不允许修改栈中指针的内存地址。如果将变量的栈中内存地址放到堆中,栈区是不能修改,堆区才能修改

    相关文章

      网友评论

          本文标题:如何使用Block来修改外部变量

          本文链接:https://www.haomeiwen.com/subject/ilylwttx.html