将来跳槽用

栈块 堆块 全局块

2018-06-20  本文已影响0人  foolish_hungry
void (^block) (void);
    BOOL flag = YES;
    if (flag) {
        block = ^{
            NSLog(@"Block A");
        };
    } else {
        block = ^{
            NSLog(@"Block B");
        };
    }

    block();

编译器会给if 和 else 两个范围内的block 分配栈内存, 但是只要出了这个范围之后, 栈内存有可能被覆写, 所以程序可能会发生崩溃.

解决办法: 给块对象发送copy消息, 将块对象从栈上拷贝到堆上, 之后块对象就是采用引用计数来进行内存管理了, 块对象的内存不会在范围之外被覆写, 也就不会有崩溃的可能了.

修改后的代码

    void (^block) (void);
    BOOL flag = YES;
    if (flag) {
        block = [ ^{
            NSLog(@"Block A");
        } copy];
    } else {
        block = [ ^{
            NSLog(@"Block B");
        } copy];
    }

    block();

全局块

@interface ViewController ()

@end

// 全局块
void (^globalBlock) (void) = ^{
    NSLog(@"hello");
};

@implementation ViewController

这种块不需要捕获任何状态, 块的内存区域在编译的时候, 就确定好了, 全局块的拷贝是个空操作, 因为全局快不可能被系统回收, 可以将它看作为单例.

参考 (编写高质量iOS 与 OX 52 个有效方法)

上一篇 下一篇

猜你喜欢

热点阅读