哪些事情不要拿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_;

results matching ""

    No results matching ""