iOS 使用 (int) 转换 NSDictionary 中的值失败

iOS converting value in NSDictionary with (int) fail

我有一个 NSDictionary 包含 2 key/value 对:

NSDictionary *dic = @{@"tag":@2,                //NSNumber
                      @"string":@"someString"}; //NSString

NSLog(@"%i",(int)[dic objectForKey:@"tag"]);      //print out 34
NSLog(@"%i",[dic objectForKey:@"tag"] intValue]); //print out 2

为什么 "converting id value to int with (int)" 得到错误的结果而不是相反的结果?他们的转化水平不同吗?

@2 不是 int,而是 NSNumber,您不能将 NSNumber 转换为 int。您必须使用 intValue 方法才能获得正确的结果。

Why does "converting id value to int with (int)"get me the wrong result but not the other way? are they in different levels of conversion?

id是指针类型。 id 个指针指向内存中的 Objective-C 个对象。通过将 id 强制转换为 (int),您只是将指针的(部分)位模式重新解释为 int,这是毫无意义的。如果您想可靠地从 Objective-C 对象中获取原始值,则必须调用 NSStringNSNumber 的正确转换方法。

如果 在使用 NSNumber 进行指针转换的情况下,您似乎获得了 2 的 "correct" 值,即 可能是 因为 Objective-C 运行时使用了一种称为 tagged pointers 的优化技术,因此小对象并不是真正创建和分配的,而是它们的语义(数字的位NSNumber 对象存储)被填充到指针的未使用位中。

方法 objectForKey: returns 指向 NSNumber 对象 @2 的指针,而不是存储在对象本身中的值。因此,您正在对指针进行类型转换,而不是值 2。在最后一行中,您没有对对象进行类型转换,而是访问了一个名为 intValue 的 属性,其中 returns 表示为 int 的对象的值.

NSDictionary 包含具有键值对的对象,但您将 int(@2) 传递给对象

NSDictionary *dic = @{@"tag":@2,                //NSNumber
                      @"string":@"someString"};

所以像

一样把int改成NSNumber
NSDictionary *dic = @{@"tag":[NSNumber numberWithInt:2];,@"string":@"someString"};

你可以得到它..

int number = [[dict objectForKey:@"tag"] intValue];