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 个有效方法)
网友评论