Block深入浅出

2020-08-07  本文已影响0人  一直在路上66

一:什么事Block

Block 是将函数及其执行上下文封装起来的对象。

基本使用:

@property(nonatomic, copy)void(^dismissBlock)(void);
@property(nonatomic, copy)void(^dismissBlock2)(UIView *view);
void (^logBlock)(NSString *)=^(NSString *paramStr){
};

在方法中生命

- (void)getMyBlock:(void(^)(int aa,int bb))myBlock;

typedef 返回类型(^block名)(参数类型 [参数名可选]);

typedef void(^MyBlock)(void);
 
@property(nonatomic, copy) MyBlock myBlock;

二:Block变量截获

1、局部变量截获 是值截获。 比如:

    NSInteger num = 3;
    NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
      return num *n;
    };
    num = 1;
    NSLog(@"%zd",block(2));

这里的输出是 6 而不是 2,原因就是对局部变量 num 的截获是值截获。 同样,在 block 里如果修改变量 num,也是无效的,甚至编译器会报错。

   NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
    void(^block)(void) = ^{
        NSLog(@"%@",arr);
        [arr addObject:@"4"];

    };
    [arr addObject:@"3"];
    arr = nil;
    block();

打印为 1,2,3 局部对象变量也是一样,截获的是值,而不是指针,在外部将其置为 nil,对 block 没有影响,而该对象调 用方法会影响

2、局部静态变量截获 是指针截获。

    static NSInteger num = 3;
    NSInteger(^block)(NSInteger) = ^NSInteger(NSInteger n){
      return num *n;
    };
    num = 1;
    NSLog(@"%zd",block(2));

输出为 2,意味着 num = 1 这里的修改 num 值是有效的,即是指针截获。 同样,在 block 里去修改变量 m,也是有效的。

3、全局变量,静态全局变量截获:不截获,直接取值。

Block 的几种形式

  NSLog(@"%@",[^{
        NSLog(@"globalBlock");
    } class]);
NSInteger num = 10;
    NSLog(@"%@",[^{
        NSLog(@"%zd",num);
    } class]);

输出为stackBlock

__block底层实现原理

总结:加入了__block的表示后,栈中的指针地址永久的被copy到堆中了,不加入__block时候,只是在block内部时候会被暂时的从栈中被copy到堆中,等block结束后又回到栈中了,因为block对象布局中有copy方法,所以可以进行copy操作

上一篇 下一篇

猜你喜欢

热点阅读