【问题标题】:String length change after save in Core Data在 Core Data 中保存后的字符串长度变化
【发布时间】:2013-02-10 08:42:54
【问题描述】:

所以这里有一个问题。

我有一个字符串

    Белый Клык-0.fb2

NSString方法长度返回16

在核心数据中保存字符串后(后端-sqlite)

NSString 方法长度返回 17,但视觉上字符串保持不变

    Белый Клык-0.fb2

显然方法 isEqualToString: return NO

经过大量的实验,我猜想问题出在这封信上:

    й

删除此字母可解决问题。

但它一直让我发疯,为什么会发生这样的事情?

这里的解决方法可行,但不满足我:

  1. stringByReplacingPercentEscapesUsingEncoding: - 需要在数据库查询中和之后转换字符串
  2. 音译整个字符串 - 有点破解

这里是 dosnt 有效的解决方法:

  1. stringWithUTF8String
  2. Converting escaped UTF8 characters back to their original form

请帮助我了解在 Core Data 中保存后字符串发生了什么。

还有更优雅的解决方案吗?

【问题讨论】:

  • 这可能是与unicode normalization 相关的问题。只需尝试将您的 coredata 字符串与[yourOriginalString decomposedStringWithCanonicalMapping] 进行比较,看看是否有效...(我已经对其进行了测试,当在您的示例中的字符串中调用时它返回的长度为 17)
  • 谢谢!可悲的是,这确实有效,但我什至没有听说过规范映射。你可以添加一个答案吗?我把它标记为正确答案。
  • 如果您确实需要保留原始字符串,包括组合字符,您必须将其存储为 NSData:[myString dataUsingEncoding:NSUTF16StringEncoding]

标签: objective-c core-data nsstring nsstringencoding


【解决方案1】:

该问题可能与unicode normalization 有关。所以 Coredata 似乎存储了分解后的字符串(所以й 计数为 2 - 一个用于字母,一个用于重音),这就是为什么你会得到长度差异的原因。如果您在将原始字符串与 Coredata 返回的内容进行比较之前尝试分解原始字符串,它应该可以工作:

[yourOriginalString decomposedStringWithCanonicalMapping]

现在,这背后的原因超出了我的专业领域。我经常使用 coredata 来管理我的模型,并且多次使用希腊/俄语字符串,从未遇到过这样的问题。如果有人可以对此进行扩展并有所启发,我也会对这个主题非常感兴趣。

【讨论】:

  • 数据库通常会进行此类规范分解以增强排序和搜索性能。当数据库知道内部表示总是被分解时,相等性测试只是按位比较。
  • @NikolaiRuhe 有道理,但NSString 的比较方法不应该自动处理吗?
  • 确实有,但性能提升来自于还没有 NSStrings 的地方:数据库的内部排序、索引和搜索都需要快速比较字符串。增强的性能是因为您知道您不需要更复杂的组合字符感知算法。
  • @NikolaiRuhe 是的,在 db 查询的情况下确实会发生这种情况(尽管一般来说,coredata 存储也可以是 XML 文件),但这里的问题是对象从商店中提取的(在本例中为 NSString)与另一个 NSString 没有按预期进行比较。顺便感谢您的见解!
  • 啊,现在我明白了。您的意思是 NSString 的 isEqual: 应该透明地处理字符组合?好吧,事实并非如此。字符组合/分解是错误的常见来源,或者至少是应用程序工程师无法解决的混乱。至少 Cocoa 的 isEqual: 实现与大多数 unicode 框架类似。如果需要自动分解,可以使用compare:
猜你喜欢
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-28
  • 2022-11-05
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
相关资源
最近更新 更多