如何在Objective-C类中设置可选Block?解决调用未赋值Block崩溃问题
解决Objective-C空Block调用崩溃的问题
哥们,你这个问题我太熟了——你用@try/@catch抓不住崩溃的核心原因是:空Block直接调用根本不是OC层面的异常,是底层的内存访问错误,OC的@try/@catch只能捕获NSException这类OC抛出的异常,对这种C层面的空指针函数调用完全无效,所以崩溃还是会发生。
下面给你两个最常用的解决方案:
1. 调用前强制判空(最直接的基础方案)
每次调用Block之前,先检查它是否不为nil,这是最稳妥的防御性编程方式:
// 调用_onConnectBlock前先判空 if (_onConnectBlock) { _onConnectBlock(); } // _onCloseBlock同理 if (_onCloseBlock) { _onCloseBlock(); }
原理很简单:Objective-C里Block是对象类型,nil的Block本质是空指针,直接调用相当于尝试执行空指针指向的函数,会触发EXC_BAD_ACCESS,而判空就能避免这种情况。
2. 给Block设置默认空实现(更优雅的方案)
如果你不想每次调用都写判空代码,可以在类初始化的时候给Block赋值一个空的实现,这样就算外部没有设置Block,调用时也不会崩溃:
// 在类的init方法里初始化默认Block - (instancetype)init { self = [super init]; if (self) { // 给两个Block设置空实现 _onConnectBlock = ^{}; _onCloseBlock = ^{}; } return self; }
之后你就可以直接调用_onConnectBlock()或者self.onConnectBlock(),不用再担心空指针问题——因为Block永远不会是nil,最多执行一个空操作。
另外补充一句:如果你的类支持懒加载,也可以重写Block属性的getter方法,在第一次访问时自动赋值空实现,效果是一样的。
内容的提问来源于stack exchange,提问作者maxisme
相关产品推荐
相关产品推荐

