关于block中调用外部基本数据类型变量问题

先看两种方式的代码:

- (void)blockDemo1{

    __block int num = 10;
    int *p = #

    NSLog(@"=>%p",p);
    // 定义一个block
    void (^task)() = ^{

        NSLog(@"==>%p-%d",&num,num);
        NSLog(@"=>%d",*p);
    };
    num = 20;
    NSLog(@"=>%p",p);
    // 执行block
    task();

    NSLog(@"===>%p-%d",&num,num);
    NSLog(@"=>%d",*p);
}


##运行结果
2017-02-21 20:04:00.117 04-Block的面试题[4856:577406] =>0x7fff55e95668
2017-02-21 20:04:00.117 04-Block的面试题[4856:577406] =>0x7fff55e95668
2017-02-21 20:04:00.117 04-Block的面试题[4856:577406] ==>0x600000232958-20
2017-02-21 20:04:00.117 04-Block的面试题[4856:577406] =>10
2017-02-21 20:04:00.117 04-Block的面试题[4856:577406] ===>0x600000232958-20
2017-02-21 20:04:00.118 04-Block的面试题[4856:577406] =>10

- (void)blockDemo1{

    int num = 10;
    int *p = #

    NSLog(@"=>%p",p);
    // 定义一个block
    void (^task)() = ^{

        NSLog(@"==>%p-%d",&num,num);
        NSLog(@"=>%d",*p);
    };
    num = 20;
    NSLog(@"=>%p",p);
    // 执行block
    task();

    NSLog(@"===>%p-%d",&num,num);
    NSLog(@"=>%d",*p);
}

##运行结果
2017-02-21 20:05:19.534 04-Block的面试题[4877:578778] =>0x7fff5536766c
2017-02-21 20:05:19.534 04-Block的面试题[4877:578778] =>0x7fff5536766c
2017-02-21 20:05:19.534 04-Block的面试题[4877:578778] ==>0x600000055478-10
2017-02-21 20:05:19.534 04-Block的面试题[4877:578778] =>20
2017-02-21 20:05:19.535 04-Block的面试题[4877:578778] ===>0x7fff5536766c-20
2017-02-21 20:05:19.535 04-Block的面试题[4877:578778] =>20

不同点:是基本数据类型前面加了一个”block”

加”block”:
这种情况下,系统在编译block时,发现有个num变量,外部没有用__block修饰,系统会在堆区中创建一个同名同类型的变量,在真正执行代码的时候,如果没有对num进行修改的操作,那么就会直接调用堆区中的num的值,这个值是在编译的时候已经赋给堆区变量的,打印(简单地说这个时候block内部与外部没有任何的关系),当block执行完毕后,调用的num还是之前的栈区中创建的num
加”block”:
这个时候,程序在编译block代码块的时候,发现num是被__block修饰的,就不会上来就在堆区中创建num变量,而是在执行到这里的时候才去按照外部的同名变量去在堆区中创建num,与此同时,会修改外部变量的地址,这个地址是堆区中num的地址,所以在最后打印num的地址,是指向堆区的,因而获取的值也是堆区中num的值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值