哪些事情不要拿Block 来做
在很多状况下,使用block 相当方便,但由于因为block 的内存管理问题,有些事情使用block 反而相当痛苦,就我个人而言,最痛苦的经验应该就是拿block 写回传。举个例子,假如要使用block 来写一个费式数列,可能会写成这样(这边是开启ARC 的环境):
int (^fibs)(int) = ^(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fibs(n-1) + fibs(n-2);
};
看起来好像没有问题,但是一执行就会马上crash。
原因是在fibs 这个Block 的scope 里头,fibs 这个变量被指向NULL。一般来说,对nil 物件做任何Objective-C 调用都没事,但是如果一个Block 变量指向NULL,一调用就会因为Bad Access 错误而crash。而当你写出这段一定会crash 的程式,compiler 也都不会发出警告…谁说用了ARC 就不会有内存管理问题呢?
那么,我们在fibs
前面加上个__block看看?
__block int (^fibs)(int) = ^(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fibs(n-1) + fibs(n-2);
};
结果,这样的程式会因为循环retain 而造内存泄露。
所以这段code 要写成这样才不会有问题:
__block int (^fibs)(int);
int (^fibs_)(int) = ^(int n) {
if (n == 0) {
return 0;
}
if (n == 1) {
return 1;
}
return fibs(n-1) + fibs(n-2);
};
fibs = fibs_;