iOS 使用block属性问题

2017-07-02  本文已影响0人  zhaihongxia

1.block属性的声明

block属性的声明,需要copy修饰符,因为只有copy后的block才会在堆中,栈中的block的生命周期是和栈绑定的

2.block线程安全

在声明block属性时需要确认“在调用block时另一个线程有没有可能去修改block?”确定不会有,block声明可以用nonatomic。不确定(通常是不确定),需要 声明block属性为atomic,先保证变量的原子性。

比如这样一个block类型

typedef   void  (^MyBlockType)(int);

属性声明:@property(copy)  MyBlockType   myBlock;

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

正确的代码是(ARC):

MyBlockType    block = self.myBlock;//block现在是本地不可变

if(block){

block(123);

}

非ARC下需要手动retain一下,否则属性被置空,本地变量就成了野指针

MyBlockType  block = [self.myBlock   retain];

if(block){

block(123);

}

[block release];

3.循环引用

ARC下,由于__block抓取的变量一样会被block retain,所以必须用弱引用才可以解决循环引用问题,iOS5之后用__weak。

__weak     typeof(self)      weakSelf = self;

self.myBlock = ^(int   paramInt)   {

[weakSelf  anotherFunc];

};

非ARC,无法使用弱引用,用__block来修饰变量,它不会被block所retain的

__block  typedef(self)    blockSelf = self;

self.myBlock = ^(int  paramInt)  {

[blockSelf   anotherFunc];

};

上一篇下一篇

猜你喜欢

热点阅读