Flutter iOS集成MLKit数字墨水识别初始化识别器报错如何解决?
问题原因与解决方案
核心问题1:重复创建识别器导致内存溢出
你当前的代码每次执行识别逻辑时都会新建DigitalInkRecognizer实例,ML Kit识别器内部会加载TFLite模型并占用mmap内存,旧实例没有被主动释放的情况下,多次调用后内存就会被占满,触发Unable to mmap file descriptor (Cannot allocate memory)错误。
修复方案:
- 将识别器改为全局/类级别属性,仅在首次使用、语言切换时才初始化,避免每次识别重复创建
- 若需要动态切换识别模型,创建新实例前先将旧的
digitalInkRecognizer置为nil,强制释放占用的资源
核心问题2:Flutter编解码器不支持NSError类型
崩溃的直接触发原因是你将原生NSError对象直接作为details参数传给了FlutterError,Flutter的标准序列化编解码器无法处理NSError类型,因此抛出Unsupported value for standard codec异常。
修复方案:
返回错误前先将NSError转换为可序列化的类型,比如错误描述字符串、包含错误码和信息的字典,再传给FlutterError的details参数。
优化后代码示例
// 类级别属性,仅初始化一次 private var digitalInkRecognizer: DigitalInkRecognizer? private var currentUseLanguageTag: String? func handleRecognitionRequest(languageTag: String, mlStrokes: [Stroke], result: @escaping FlutterResult) { // 仅当语言切换或识别器未初始化时才创建新实例 if currentUseLanguageTag != languageTag || digitalInkRecognizer == nil { guard let identifier = DigitalInkRecognitionModelIdentifier(forLanguageTag: languageTag) else { result(FlutterError( code: "ERROR", message: "No model for language tag found or the language tag could not be parsed", details: nil )) return } let model = DigitalInkRecognitionModel(modelIdentifier: identifier) let options = DigitalInkRecognizerOptions(model: model) // 主动释放旧识别器资源 digitalInkRecognizer = nil digitalInkRecognizer = DigitalInkRecognizer.digitalInkRecognizer(options: options) currentUseLanguageTag = languageTag } let ink = Ink(strokes: mlStrokes) digitalInkRecognizer?.recognize(ink: ink) { [weak self] recognitionResult, error in guard let _ = self else { return } if let res = recognitionResult { var candidates = [[String: Any?]]() for candidate in res.candidates { candidates.append(["text": candidate.text, "score": candidate.score]) } result(candidates) } else { // 转换NSError为字符串后再返回给Flutter let errMsg = error?.localizedDescription ?? "Unknown recognition error" result(FlutterError( code: "ERROR", message: "Unable to recognize handwriting", details: errMsg )) } } }
内容的提问来源于stack exchange,提问作者skuallpa
相关产品推荐
相关产品推荐

