2

我正在尝试为<NSCoding>我的一个类实现协议。我在对此类的一个属性进行序列化\反序列化时遇到了一个问题。该属性的类型为:NSLocale

这是我写的一个(猕猴桃)测试来理解的行为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

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

4

1 回答 1

3

笔记

根据下面的 CodaFi 评论,这似乎是NSLocale.

NSCoder产生一个NSCFLocale实例,而直接分配返回一个NSLocale.

由于NSLocaleandNSCFLocale执行不同的相等性检查(前者似乎使用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

令人惊讶的是,取消归档后返回的实例l1l3!

于 2013-06-23T18:55:56.627 回答