iOS 15.6下Swift调用Vision文本识别内存持续增长的优化求助
兄弟,我之前在批量用Vision做文本识别时也踩过内存持续上涨的坑,结合你的代码和实际踩坑经验,给你几个可行的优化方向:
复用文本识别请求对象
你现在每次调用textRecognition都会新建VNRecognizeTextRequest,频繁创建销毁这类框架对象会导致内存无法及时回收,还会增加额外开销。建议把请求对象改成类的懒加载属性,只初始化一次:// 在你的ViewController或业务类中定义 private lazy var textRecognitionRequest: VNRecognizeTextRequest = { let request = VNRecognizeTextRequest(completionHandler: self.handleDetectedText) request.recognitionLevel = .accurate request.recognitionLanguages = ["en_US"] request.usesLanguageCorrection = false return request }()之后在
textRecognition方法里直接复用这个请求,不用每次重新创建。修复潜在的循环引用
你的请求completion handler直接引用了self,这有可能形成循环引用,让相关对象无法被ARC正常回收。建议创建请求时用弱引用捕获self:private lazy var textRecognitionRequest: VNRecognizeTextRequest = { let request = VNRecognizeTextRequest { [weak self] request, error in self?.handleDetectedText(request: request, error: error) } request.recognitionLevel = .accurate request.recognitionLanguages = ["en_US"] request.usesLanguageCorrection = false return request }()用autoreleasepool包裹识别逻辑
Vision执行识别时会生成一些自动释放池管理的临时对象,批量处理时这些对象可能不会被及时回收。把perform调用放在autoreleasepool里,能强制在代码块结束时释放这些临时对象:DispatchQueue.global(qos: .userInitiated).async { autoreleasepool { do { try imageRequestHandler.perform([self.textRecognitionRequest]) } catch let error { print("Error \(error)") } } }及时清理图像资源
确保传入的CGImage在识别完成后没有被意外持有,如果是从UIImage转换而来的CGImage,处理完后可以把原UIImage置为nil,避免不必要的内存占用。检查结果处理逻辑
虽然你现在的handleDetectedText直接return了,但如果后续要处理识别结果,一定要注意不要持有大对象或未及时释放的资源;另外主线程的UI操作也要确保没有意外持有多余引用。
如果以上优化后内存还是持续增长,也可以排查下iOS 15.6的Vision框架是否有已知内存泄漏问题——如果能升级到更高版本的iOS,可能会修复这类系统层面的问题。
备注:内容来源于stack exchange,提问作者Dave

