gpt4 book ai didi

objective-c - 比较用 const 整数实例化的 NSNumber 对象的指针

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:05:50 26 4
gpt4 key购买 nike

今天我正在审查一些代码,我被完全愚弄了。我在代码中看到了这样的东西

...
NSNumber *myNumber = [NSNumber numberWithInteger:4];
...
if (myNumber == [NSNumber numberWithInteger:4)
{
...
}
...

当我读到 if 条件时,我的第一个想法是:哇!你怎么能那样做?您显然是在此处比较指针,因此当您在正确的位置生成实例时,当然不会执行此 if 中的代码,因此对象永远不会相同!

令我(大)吃惊的是,实际上 if 被执行了!所以我生成了一些测试来加深正在发生的事情,我得到了这个:

NSInteger intValue = 5;
NSNumber *anIntNumber = [NSNumber numberWithInteger:intValue];
NSNumber *anotherIntNumber = [NSNumber numberWithInteger:intValue];
NSLog(@"%p vs %p -> %@", anIntNumber, anotherIntNumber, ((anIntNumber == anotherIntNumber) ? @"YES" : @"NO"));

这是结果:

0x7462560 vs 0x7462560 -> YES

然后我想起我在堆栈溢出中的某处读到常量 NSString 在程序开始时存储在内存堆栈中的某处。然后我运行这段代码来检查 NSString 实例是否发生了同样的事情:

NSString *aString = @"FOO";
NSString *anotherString = @"FOO";
NSLog(@"%p vs %p -> %@", aString, anotherString, ((aString == anotherString) ? @"YES" : @"NO"));

这是结果:

0x35cc vs 0x35cc -> YES

所以是的,实例是相同的,尽管它不是故意的。根据这些结果,我可以想象系统也会在内存堆栈中的某处分配所有用常量整数实例化的 NSNumber 对象。

但我现在的问题是:他们为什么要这样做?内存的浪费难道不是比生成实例的时间更重要吗?

然后我想:花车呢?由于二进制表示和所有这些东西, float 不能真正与等于运算符进行比较。这是最后一个测试:

float floatValue = 5.41553f;
NSNumber *aFloatNumber = [NSNumber numberWithFloat:floatValue];
NSNumber *anotherFloatNumber = [NSNumber numberWithFloat:floatValue];
NSLog(@"%p vs %p -> %@", aFloatNumber, anotherFloatNumber, ((aFloatNumber == anotherFloatNumber) ? @"YES" : @"NO"));

这是唯一的预期结果!

0x712f180 vs 0x74299a0 -> NO

您对此有何看法?你真的认为这是最好的行为(并且更符合逻辑)吗?感谢您分享您的知识!

最佳答案

== 运算符与 NSNumber 的使用仅在某些情况下有效,因为 NSNumber 实现在内部使用一些全局实例来表示整数 0 到 X(12 或15 左右)。

在内存中容纳十几个 NSNumber 对象的内存是微不足道的。

无论如何,切勿使用 == 运算符进行均等检查。始终使用 isEqual:(或其变体)。永远不要像这样依赖实现细节或编译器优化。

关于objective-c - 比较用 const 整数实例化的 NSNumber 对象的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13995726/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com