Farlanki

关于block与copy关键字

字数统计: 301阅读时长: 1 min
2016/01/27 Share

在创建一个block类型的属性时,经常会看到这个属性被加上了copy关键字,例如:

1
@property (nonatomic,copy) MyBlock block;

这是为什么呢?
首先,block有三种:

  • _NSConcreteStackBlock
  • _NSConcreteGlobalBlock
  • _NSConcreteMallocBlock

_NSConcreteStackBlock设置在栈上.
_NSConcreteGlobalBlock设置在程序的数据区域,和全局变量一样.
_NSConcreteMallocBlock分配在堆中.

当一个block设置在栈中时,如果其所属的作用域结束,该block就被废弃.如果一个方法需要返回一个block,如何解决这个问题呢?
block提供了将其复制到堆上的方法来解决这个问题.

1
2
3
4
5
typedef int (^blk_t)(int);
blk_t func(int rate){
return ^(int count){return rate * count};
}
//返回处使用block会发生异常
1
2
3
4
5
typedef int (^blk_t)(int);
blk_t func(int rate){
return [^(int count){return rate * count} copy];
}
//正常

在ARC中,block在被返回前自动被copy一次,直接return就行.然而,block作为参数时,需要手动copy

1
2
3
4
5
6
7
-(id) getBlockArray{
int val = 10;
return
[[NSArray alloc]initWithObjects:
[^{NSLog(@"blk0:%d",val);}copy],
[^{NSLog(@"blk1:%d",val);}copy],nil ];
}

另外,block有自动捕获变量的功能,当一个block被copy时,其自动捕获的变量也被复制到堆中,并且被block持有.

CATALOG