如何正确序列化\反序列化NSLocale?

时间:2013-06-23 18:23:49

标签: ios objective-c foundation kiwi

我正在尝试为我的一个类实现协议<NSCoding>。 我在seralizing \ deseralizing这个类的一个属性时遇到了一个问题。该属性的类型为:NSLocale

我在这里写了一个(Kiwi)测试来理解NSLocale的行为:

   NSLocale *locale = [NSLocale currentLocale];
   NSData *data = [NSKeyedArchiver archivedDataWithRootObject:locale];
   NSLocale *locale2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];

   NSLog(@"1) %@", [locale localeIdentifier]); //=> "en_US"
   NSLog(@"2) %@", [locale2 localeIdentifier]); //=> "en_US"
   [[locale should] equal:locale2]; //=>fail

   [[[NSLocale currentLocale] should] equal:[NSLocale currentLocale]]; //=> pass

测试失败。你们知道为什么吗?

1 个答案:

答案 0 :(得分:3)

注意

根据下面的CodaFi评论,这似乎是NSLocale的实施问题。

NSCoder生成NSCFLocale个实例,而直接分配则返回NSLocale

由于NSLocaleNSCFLocale执行不同的等式检查(前者似乎使用CFEqual(),后者isEqualToString:)这导致了不公平的暴露下方。


原始帖子

这不是一个答案,因为我不知道发生了什么,但我不能在评论中说明这一点。这是一些测试的奇怪结果

如果您“手动”声明NSLocale的实例,一切都按预期工作

NSLocale * l1 = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:l1];
NSLocale *l2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"%i", [l1 isEqual:l2]); // => 1, aka YES

但是,如果您将l1声明为[NSLocale currentLocale],那么就会出现问题

NSLocale * l1 = [NSLocale currentLocale];    
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:l1];
NSLocale *l2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(@"%i", [l1 isEqual:l2]); // => 0, aka NO

坦率地说,我和你一样感到困惑。


额外信息:

这是另一个测试的结果

NSLocale * l1 = [NSLocale currentLocale];
NSLocale * l3 = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:l1];
NSData *data1 = [NSKeyedArchiver archivedDataWithRootObject:l3];
NSLocale *l2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLocale *l4 = [NSKeyedUnarchiver unarchiveObjectWithData:data1];

NSLog(@"\n%p\n%p", l1, l2);    // => 0x9849da0
NSLog(@"\n%p\n%p", l3, l4);    // => 0x9866770
NSLog(@"%i", [l1 isEqual:l2]); // => 0x9866770
NSLog(@"%i", [l3 isEqual:l4]); // => 0x9866770

令人惊讶的是,取消归档l1后返回的实例与l3相同!