block 初探

2021-02-22  本文已影响0人  easy_luo
@interface SecondViewController ()

@property (nonatomic, copy) void(^block)(void);
@property (nonatomic, copy) NSString *name;

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.navigationItem.title = @"SecondViewController";
    
    [self functionC];
}

- (void)dealloc{
    NSLog(@"SecondViewController dealloc");
}

- (void)functionC{
    __weak typeof(self) weakSelf = self;//确保block封装对象弱引用self
    self.block = ^{//NSMalloc block 堆block
        __strong typeof(self) strongSelf = weakSelf;//1、确保block开始执行时,强引用self引用计数+1,防止往后执行中self被释放。2、同时强指针可以指针方式访问 成员的属性
        strongSelf->_name = @"jack";
        NSLog(@"call block set name");
    };
    
    
    void(^callBlock)(void) = ^{
        __strong typeof(self) strongSelf = weakSelf;
        if (strongSelf.block) {//self.block 不一定会执行,如果self提前释放了,self的block也就被释放了。但callBlock一定会被执行后才被释放,被dispatch_after 强引用着。
            strongSelf.block();
        }
    };
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{//模拟网络请求异步回来
        callBlock();//强引用+1
        NSLog(@"call block");
    });
}

@end

全局block, 栈block, 堆block

- (void)test{
    __weak typeof(self) weakSelf = self;
    void(^ __weak doWork)(void) = nil;
    {
        int a = 0;
        void(^doWork1)(void) = ^{//左边捕获外部变量,__NSStackBlock__; 右边强引用,copy block,是__NSMallocBlock__
            a;
            weakSelf.name = @"90";
            NSLog(@"=============2222");
        };
        doWork = doWork1;//弱引用赋值
    }
    doWork();// doWork1出了作用域后会调用block_release释放堆block, 会crash
    
    int b = 5;
    void(^ __weak doWork)(void) = ^{
        b;
        NSLog(@"__NSGlobalBlock__");
    };
    //doWork 没有截获任何外部变量,GlobalBlock。 self.block 对全局 doWork block 进行 copy,仍是全局 block
    doWork();
    NSLog(@"__p  == %p",doWork);

    self.block = doWork;

    void(^ __weak doWork2)(void) = doWork;

    NSLog(@"__p  == %p",doWork2);

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        block();
    });
}
上一篇 下一篇

猜你喜欢

热点阅读