SwiftUI本地化字符串导致编译卡顿的问题
SwiftUI本地化字符串导致编译卡顿的问题

SwiftUI本地化字符串导致编译卡顿的问题

问题描述

在SwiftUI中,我的使用场景为根据“压缩率”字段,返回本地化的字符串。

在代码中,使用compressionTips()方法,返回String字符串,在Text中使用LocalizedStringKey初始化方法,显示本地化的字符串。

func compressionTips() -> String {
    let rate = appStorage.imageCompressionRate
    if rate <= 0.2 {
        return "Lowest"
    } else if rate <= 0.4 {
        return "Low Quality"
    } else if rate <= 0.6 {
        return "Balanced"
    } else if rate <= 0.8 {
        return "High Quality"
    } else {
        return "Lossless"
    }
}
Text(LocalizedStringKey:compressionTips())

但是,这个代码会导致长时间的编译。

并且输出Xcode报错:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions

把compressionTips()方法拆分,仍然无法解决长时间编译的问题:

let tip = compressionTips()
Text(LocalizedStringKey:tip)

问题原因

当使用LocalizedStringKey方法时:

Text(LocalizedStringKey(compressionTips()))

或String(localized:)方法

Text(String(localized: compressionTips()))

都可能在SwiftUI的视图树中引发编译卡顿,尤其是在 compressionTips() 是依赖绑定数据(如 @ObservedObject, @State, @AppStorage)的时候。

解决方案

应该避免视图内容调用逻辑函数,可以将compressionTips()的调用结果提前计算为局部变量或计算属性,再传入Text。

推荐使用计算属性解决这一问题:

struct SettingsView: View {
    @ObservedObject var appStorage = AppStorage.shared

    var compressionLocalizedKey: LocalizedStringKey {
        let rate = appStorage.imageCompressionRate
        if rate <= 0.2 {
            return "compression.level.lowest"
        } else if rate <= 0.4 {
            return "compression.level.low"
        } else if rate <= 0.6 {
            return "compression.level.balanced"
        } else if rate <= 0.8 {
            return "compression.level.high"
        } else {
            return "compression.level.lossless"
        }
    }

    var body: some View {
        VStack {
            Text(compressionLocalizedKey) // 编译无压力,支持本地化
        }
    }
}

这个方案可以解决本地化字符串导致编译卡顿的问题。

因此compressionLocalizedKey是一个简单的属性,SwiftUI编译器更容易处理。

Text直接接收LocalizedStringKey,这是SwiftUI本地化字符串的首选用法。

避免了运行时字符串查找和嵌套函数调用,降低视图 diffing 成本。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注