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

use*_*951 14 unicode core-data ios

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

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");
Run Code Online (Sandbox Code Playgroud)

我收到了这个错误:

(lldb) po error
domain: @"NSCocoaErrorDomain" - code: 1671
Run Code Online (Sandbox Code Playgroud)

嗯......我该怎么办?

Tom*_*ton 19

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

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

NSString *testNSString = @"Rameeee! ";
[newManagedObject setValue:testNSString forKey:@"name"];
Run Code Online (Sandbox Code Playgroud)

完整的往返行程完全按预期工作,甚至UILabel在文本视图单元格中正确显示.

在此输入图像描述

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

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

"\U05d4\U05d4\U05d9\U05ea\U05e8\U05d2\U05e9\U05d5\U05ea \U05db\U05dc \U05db\U05da \U05d2\U05d3\U05d5\U05dc\U05d4 \Ud83d"
Run Code Online (Sandbox Code Playgroud)

实际上,您无法使用这些内容构造字符串文字而没有一些显着的困难.编译器抱怨最后一个字符\Ud83d是"无效的通用字符",编译失败.看一下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"];
Run Code Online (Sandbox Code Playgroud)

保存没有错误,并再次完成往返并正确显示在UILabel:

在此输入图像描述

这一切意味着什么:

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

与评论中给出的字符串相关的更新:

NSString *testNSString = @"                                ?      ?  ? ?     ";
[newManagedObject setValue:testNSString forKey:@"name"];
Run Code Online (Sandbox Code Playgroud)

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