OC和Swift中Block变量截获区别

2019-07-30  本文已影响0人  林夕copy

OC

    NSInteger num = 3;
    NSLog(@"%p", &num);
    
    NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
        NSLog(@"%p", &num);
        return n*num;
    };
    
    num = 1;
    NSLog(@"%p", &num);
    
    
    NSLog(@"%d",block(2));
运行结果如下图: OCResult.png

输出结果为6
OC中Block为值截获,即在编译时,block会深拷贝(deep copy)num,在后续调用闭包时使用的是拷贝后的num,所以原变量改变不会改变Block的运行结果。

Swift

var num = 3

withUnsafePointer(to: &num) {
    print("During calling: \($0)")
}
let block1: ((Int) -> Int) = { n in
    withUnsafePointer(to: &num) {
        print("During calling: \($0)")
    }
    return n*num
}

num = 1

print(block1(2))
运行结果如下图: SwiftResult.png

输出结果为2
Swift中Block捕获变量后会强引用,即出了原变量作用域后Block依然可以获取到变量或者常量。所以当原变量改变时,闭包运行结果也会改变。
为了优化,如果一个值不会被闭包改变,或者在闭包创建后不会改变,Swift 可能会改为捕获并保存一份对值的拷贝。

上一篇下一篇

猜你喜欢

热点阅读