You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 5.5使用Method Swizzling替换NSURL的initWithString崩溃如何解决

问题原因

1. 直接崩溃原因

你的代码崩溃在let originalMethod = class_getInstanceMethod(NSURL.self, original)!这一行,原因是class_getInstanceMethod返回了nil,你强制解包可选值触发了致命错误。
出现nil的原因是NSURL属于类簇,initWithString:的具体实现没有放在公开的NSURL基类中,而是存在于苹果内部私有的子类实现里,直接从NSURL类上无法获取到这个实例方法的指针。

2. 其他隐藏问题

就算你解决了方法获取的问题,代码还有以下问题会导致功能异常:

  • 方法签名不匹配:你定义的log_initWithString没有声明返回值,Swift默认推断为Void,但原生initWithString:的返回值是可选NSURL实例,方法类型编码不匹配,交换后会出现内存错误。
  • 覆盖场景缺失:Swift中的URL是结构体类型,它的init(string:)构造器有原生Swift实现,大部分场景下不会桥接调用ObjC的NSURL方法,就算hook成功NSURL的对应方法,也覆盖不到Swift中URL的创建场景。
  • 动态派发缺失:你给NSURL扩展加的log_initWithString只加了@objc,缺少dynamic修饰符,无法保证走ObjC runtime的动态派发,可能导致runtime无法识别到这个方法。

优化建议

类簇的Swizzling风险极高,苹果的内部实现随时可能调整导致逻辑失效甚至崩溃,如果只是需要拦截URL创建逻辑,更稳妥的方案是自己封装一层统一的URL创建工具方法。
如果一定要用Swizzling实现,可以尝试hookNSURL的+URLWithString:类方法,这个方法的实现直接存在于NSURL类上,更容易获取,同时注意匹配方法签名,确保返回值类型正确。


内容的提问来源于stack exchange,提问作者Faustino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 17:36:03