Swift 3.3编译报错:'self'在super.init可达的catch块中使用问题排查
解析Swift编译错误:'self' used inside 'catch' block reachable from super.init call
这个错误其实是Swift严格的初始化安全机制在“拦着”你,咱们掰扯清楚背后的原因:
核心原因:未完成的初始化导致self不安全
Swift对类的初始化有一套很严谨的安全规则:子类必须确保父类的初始化完全成功后,才能访问self(不管是直接写self.xxx,还是间接使用当前实例的上下文)。
在你的代码里,当super.init(pattern: pattern)抛出错误进入catch块时,意味着父类NSRegularExpression的初始化失败了——这时候子类MyRegex的实例根本没被完整创建出来,self处于未初始化的无效状态。虽然你在catch里只是调用了print,但编译器会认为这个catch块属于当前初始化方法的上下文,隐式关联了未就绪的self,这种情况存在严重的安全风险,所以直接报错阻止你继续执行。
两种可行的修复方案
方案1:让初始化方法抛出错误,把错误交给调用者处理
既然正则表达式解析可能失败,不如把这个错误向上传递,让使用MyRegex的代码去处理失败场景,这样就不需要在内部catch,自然避开了self的问题:
public class MyRegex : NSRegularExpression { public init(pattern: String) throws { try super.init(pattern: pattern) } }
方案2:在catch中终止程序(适用于解析失败是致命错误的场景)
如果你的业务逻辑里,正则表达式解析失败就意味着程序无法正常运行,那可以在catch里调用fatalError()直接终止程序,这样编译器就知道不会继续执行后续代码,也就不会纠结self的安全性了:
public class MyRegex : NSRegularExpression { public init(pattern: String) { do { try super.init(pattern: pattern) } catch { fatalError("Failed to parse regex pattern: \(error.localizedDescription)") } } }
内容的提问来源于stack exchange,提问作者cristianomad
相关产品推荐
相关产品推荐

