block学习

2021-04-13  本文已影响0人  青宜结鬼章

1,在传值方定义一个block

typedefvoid(^requstBlock)(NSString* str);

2,在传方声明一个这个block的属性

@property (nonatomic, copy) requstBlock requstBlock;

3,在返回方法里面

__weak typeof (self)weakSelf = self;

    if(weakSelf) {

        weakSelf.requstBlock(self.textField.text);

    }

    [self dismissViewControllerAnimated:YES completion:nil];

4,接收方

  bViewController *bvc=[[bViewController alloc]init];

    bvc.backReference=self;

    bvc.requstBlock= ^(NSString*str) {

        self.label.text= str;

    };

    [self presentViewController:bvc animated:YES completion:nil];

5,注意事项。

    5.1最简单的循环引用问题。

    5.2.1,修饰符使用copy,只有copy之后的blcok才会在堆中,栈中block的的生命周期是和栈绑定的.

    5.2.1,在生命blcok属性的时候必须线思考一个问题:在block调用时,另一个线程有没有可能去修改block,如果不确定有没有这种情况的话,最好使用atomic,也就先保证block的原子性

比如这样一个Block类型:

typedef void (^MyBlockType)(int);

属性声明:

@property (copy) MyBlockType myBlock;

这里ARC和非ARC声明都是一样的,当然注意在非ARC下要releaseBlock。

但是,有了atomic来保证基本的原子性还是没有达到线程安全的,接着在调用时需要把Block先赋值给本地变量,以防止Block突然改变。因为如果不这样的话,即便是先判断了Block属性不为空,在调用之前,一旦另一个线程把Block属性设空了,程序就会crash,如下代码:

if (self.myBlock)

{

//此时,走到这里,self.myBlock可能被另一个线程改为空,造成crash

//注意:atomic只会确保myBlock的原子性,这种操作本身还是非线程安全的

self.myBlock(123);

}

所以正确的代码是(ARC):

MyBlockType block = self.myBlock;

//block现在是本地不可变的

if (block)

{

block(123);

}

导致block内存泄漏的原因就是看是否存在相互强引用 详情参考

https://blog.csdn.net/carson_zj/article/details/53043533

上一篇 下一篇

猜你喜欢

热点阅读