IOS面试题(block相关) --- block变量截取

OC面试题目合集地址

先了解 block 截获变量

  • 基本数据类型局部变量: 截获其值
  • 对象类型局部变量: 连同所有权修饰符一起截获
  • 局部静态变量: 指针形式截获
  • 全局变量: 不截获
  • 静态全局变量: 不截获

问题1: 看例子回答

    int test1 = 2;
    
    int(^Block)(int) = ^int(int n) {
        
        return n * test1;
    };
    
    NSLog(@"result: %d", Block(6));

答案

12

block对于基本数据变量截获是截获其值 , 那么内部block截获基本数据类型2, 进行:
6 * 2 = 12


验证


问题2: 看例子回答

- (void)blockTest1 {
    
    int test1 = 2;
    
    int(^Block)(int) = ^int(int n) {
        
        return n * test1;
    };
    
    test1 = 3;
    
    NSLog(@"result: %d", Block(6));
}
例子

答案

12

相比问题1, block之后多加了一个对基本数据类型的赋值, 但是呢不要被迷惑了,
block对于基本数据变量截获是截获其 "值", 要深刻理解这句话. 简单来说, 再block之前基本数据类型是什么值, 直接写死在这个block里面, 不会变跟后面赋值个3没关系了, 可以理解成这样:

- (void)blockTest1 {
    
    int test1 = 2;
    
    int(^Block)(int) = ^int(int n) {
        // 就是2 不会变
        return n * 2;
    };
    
    test1 = 3;
    
    NSLog(@"result: %d", Block(6));
}

那么 6 * 2 = 12

验证


问题3: 看例子回答

- (void)blockTest1 {
    
    static int test1 = 2;
    
    int(^Block)(int) = ^int(int n) {
        
        return n * test1;
    };
    
    test1 = 3;
    
    NSLog(@"result: %d", Block(6));
}

答案

18

留意下这里 static int test1 = 2; 是局部静态变量, 局部静态变量block底层是以指针形式存放的, 后面有test1 = 3, 指针指向3

那么 6 * 3 = 18

验证


问题4: 看例子回答

static int test1 = 2;

- (void)blockTest1 {
    
    int(^Block)(int) = ^int(int n) {
        
        return n * test1;
    };
    
    test1 = 3;
    
    NSLog(@"result: %d", Block(6));
}

答案

18

全局变量静态全局变量 block 不截获其内容, 通俗点说调用block时候, 当时变量是什么取什么值, 那么

6 * 3 = 18

验证


问题5: 看例子回答打印结果

    NSMutableArray *arr = [NSMutableArray array];
    
    void(^Block)(void) = ^{
        [arr addObject:@"123"];
    };
    
    [arr addObject:@"456"];
    
    Block();
    
    NSLog(@"%@", arr);

答案

[ 456, 123 ]

对象类型局部变量是连同所有权修饰符一起截获, 这里其实block存放的是NSMutableArray *arr指针, 后面数组先添加了"456", 指针对象指向是["456"], 再进行block操作, 即 ["456"]插入一个新元素"123", 结果 [ 456, 123 ]

验证


问题6: 看例子回答打印结果

    __block int test1 = 2;
    
    int(^Block)(int) = ^int(int n) {
        
        return n * test1;
    };
    
    test1 = 3;
    
    NSLog(@"result: %d", Block(6));

答案

18

通俗讲, 其实__block修饰数据型, 在底层已经变成对象 (实际上是一个结构体), 不是像通常基本数据类型一样存的那个值. 那么当后续 test1 有变化时候, 内部对象(结构体中__forwarding的指针)会指向新变化值, 即

3 * 8 = 18

验证

你可能感兴趣的:(IOS面试题(block相关) --- block变量截取)