如何在CoreData中处理非标准的unicode字符?

时间:2014-06-17 10:45:15

标签: ios core-data unicode

我在网上看到的一件事就是这个

Rameeee!

所以它使用非标准字符。

我试图将其保存到coredata

   NSManagedObjectContext * parentMoc = [self managedObjectContextMainContext]; //Main parent is not nsmainqueueconcurency type. Hence, this is save
    [parentMoc performBlockAndWait:^{
        if (![parentMoc save:&error])
        {
            CLog(@"Error in Saving %@", error);// handle error
        }
    }];
    NSAssert(error==nil, @"Error must be nill");

我收到了这个错误:

(lldb) po error
domain: @"NSCocoaErrorDomain" - code: 1671
嗯......我该怎么办?

2 个答案:

答案 0 :(得分:19)

未记录错误代码1671。但是,错误代码1660,1670和1680处理字符串验证错误。那么让我们看看我们能找到什么......

无论是否有表情符号,

有效字符串的工作方式都相同。只要字符串只包含有效字符,就不需要特殊处理。提示此问题的字符串 - 已发布 - 符合此说明。此代码有效,更改保存没有错误:

NSString *testNSString = @"Rameeee! ";
[newManagedObject setValue:testNSString forKey:@"name"];

完整的往返行程完全符合预期,甚至可以在文本视图单元格的UILabel中正确显示。

enter image description here

结果很明显,原来的问题是在某处遗漏了重要的细节,因为正确的答案是你没有做任何特别的事情来处理这些角色,他们只是工作。

来自@DevFly的示例字符串提供了一个线索:

"\U05d4\U05d4\U05d9\U05ea\U05e8\U05d2\U05e9\U05d5\U05ea \U05db\U05dc \U05db\U05da \U05d2\U05d3\U05d5\U05dc\U05d4 \Ud83d"

实际上,您无法使用这些内容构造字符串文字而没有一些显着的困难。编译器抱怨最后一个字符\Ud83d是“无效的通用字符”,编译失败。看一下the relevant code chart from unicode.org证实了这一点:\Ud83d位于“高代理区域”,图表指出

  

孤立的代理代码点没有解释;因此,没有为此范围提供字符代码图表或名称列表。

这一切意味着\Ud83d不是有效的Unicode字符。它不代表任何字符,也不能转换为UTF-8等编码。

如果从末尾删除无效字符,那么就像上面一样,它正常工作而没有特殊处理:

char *testString = "\u05d4\u05d4\u05d9\u05ea\u05e8\u05d2\u05e9\u05d5\u05ea \u05db\u05dc \u05db\u05da \u05d2\u05d3\u05d5\u05dc\u05d4";
NSString *testNSString = [NSString stringWithUTF8String:testString];
[newManagedObject setValue:testNSString forKey:@"name"];

保存没有错误,并再次进行完整的往返并在UILabel中正确显示:

enter image description here

这一切意味着什么:

  • 此错误意味着您以某种方式构造了一个包含无效字节的字符串,这些字节不代表任何字符。
  • 这是不是,因为字符是Unicode,因为有效 Unicode很好。但并非每个数字十六进制值都表示Unicode字符,因此可能存在无法在字符串中使用的损坏值。
  • 由于@JimThio和@DevFly以及@SharenEayrs似乎都不想解释他们如何创建有问题的字节向量(我真的不能称之为“字符串”),因此无法说出最初导致问题的原因。但数据已损坏,期间,它只是看起来像核心数据问题,因为这是您使用数据的地方。
  • 可能的原因是,在某些时候这些字符串在代码中被更改,而不考虑不是每个字符都使用相同的字节数。像根据字符索引更改字符串这样的操作可能会导致问题。查看Apple的"Characters and Grapheme Clusters"指南以及NSHipster article on type encodings可能会有所帮助。
  • @mmarkov建议使用NSData 可能会工作但可能不会,除非您使用奇怪的代码来避免在字符串中使用这些字节(例如,您不使用dataUsingEncoding:转换为NSData)。即使它确实存在,你仍然会有损坏的数据,它迟早会咬你。
与评论中提供的字符串相关的

更新

NSString *testNSString = @"                                ☝      ✌  ✊ ✋     ";
[newManagedObject setValue:testNSString forKey:@"name"];

这样可以毫无错误地保存,并在以后完全如上所示返回到UI,包括在杀死应用程序并重新启动之后。如果这在某种程度上打破了,那么核心数据就不会破坏它。

答案 1 :(得分:0)

代码在1024和2048之间的

NSCocoaErrorDomain错误是验证错误。已在模型中设置的验证规则之一未通过。