OC面试中,Block常出现的三个问题

本文深入探讨了Objective-C中Block如何与外部变量交互,详细解释了Block内部是否能修改外部变量及其原理,同时展示了如何通过__block关键字实现对外部变量的引用与修改,以及Block在改变MutableString值时的行为区别。通过实例代码,直观呈现了Block与外部变量之间的复杂关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、输出的值是多少?为神么?

//提问,输出的值是多少
//    在定义Block的时候,如果应用了外部变量的值,会对外部变量做一个copy,把栈区的变量,拷贝到堆区
//    如果后续再改变变量的值,不回影响Block中值的变化
//    line33.默认情况下,不允许Block内部改变外部变量的值


- (void)demo1 {
    NSInteger x = 10;
    NSLog(@"前%p",&x);   //0x7fff59b4a9c8   比较大,是在栈区中的

    void(^demoBlock)() =  ^ {
       // x = 80;

        NSLog(@"%ld",x);

        NSLog(@"中%p",&x);  //0x7fe808710c60   堆区的
    };

    x = 20;
    NSLog(@"后%p",&x);      //0x7fff59b4a9c8   比较大,是在栈区中的

    demoBlock();

}

__block的使用注意为题

//  如果Block中要改变外部变量的值,需要定义的时候使用__block修饰
//  定义block时,如果使用了外部用 __block修饰的变量    在block执行完毕,外部变量的指针继续指向堆区

- (void)demo2 {
     __block NSInteger x = 10;
     NSLog(@"%ld",x);
    NSLog(@"前%p",&x);

    void (^ myBlock)() = ^ {
        x = 90;
        NSLog(@"%ld",x);
        NSLog(@"中%p",&x);
    };

    x = 20;

    myBlock();

    NSLog(@"%ld",x);
    NSLog(@"后%p",&x);
}

//输出结果  地址大的是栈区,地址小的为堆区   不要用iPhone项目演示,内存太小,看不出大小。
// 10
// 前0x7fff5804f9c8
// 90
// 中0x7fc68bc02f78
// 90
// 后0x7fc68bc02f78

3,block中改变MutableString的值

void demo3(){
    NSMutableString *str = [NSMutableString stringWithFormat:@"zhangsan"];

    NSLog(@"定义前 %p %p",str,&str);

    void (^myBlock)() = ^ {
        [str setString:@"lisi"];

        NSLog(@"in block %p %p",str,&str);
         NSLog(@"%@",str);
    };

    myBlock();
    [str setString:@"wangwu"];

    NSLog(@"定义后 %p %p",str,&str);

    NSLog(@"%@",str);

    <! 12:45:18.832 blockTest[1389:111828] Hello, World!
  blockTest[1389:111828] 定义前 0x1005001b0 0x7fff5fbff7d8
 blockTest[1389:111828] in block 0x1005001b0 0x1005003f0
 blockTest[1389:111828] lisi
 blockTest[1389:111828] 定义后 0x1005001b0 0x7fff5fbff7d8
 blockTest[1389:111828] wangwu-->
}

Editor preferences pane这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值