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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:15:08