空NSArray是平等的吗?

pol*_*sen 2 objective-c nsarray ios

我在想,为什么这段代码:

NSArray *emptyArr = [[[NSArray alloc] init] autorelease];
NSArray *emptyArrA = [NSArray arrayWithArray:emptyArr];
NSArray *emptyArrB = [NSArray arrayWithArray:emptyArr];

NSLog(@"emptyArrA == emptyArrB => %d", (emptyArrA == emptyArrB));
NSLog(@"emptyArr == emptyArrB => %d", (emptyArr == emptyArrB));
NSLog(@"emptyArrA == emptyArr => %d", (emptyArrA == emptyArr));
Run Code Online (Sandbox Code Playgroud)

输出以下内容:

emptyArrA == emptyArrB => 1
emptyArr == emptyArrB => 1
emptyArrA == emptyArr => 1
Run Code Online (Sandbox Code Playgroud)

也就是说,这些物体似乎是不同的?嗯,我想,这必须是对不可变的空NSArray的特殊情况的iOS(或CoreFoundation?)优化,然后它总是解析为同一个对象实例.

但是......这段代码:

NSLog(@"emptyArr => %p", &emptyArr);
NSLog(@"emptyArrA => %p", &emptyArrA);
NSLog(@"emptyArrB => %p", &emptyArrB);
Run Code Online (Sandbox Code Playgroud)

输出(在我的机器上):

emptyArr => 0xbfffdd64
emptyArrA => 0xbfffdd60
emptyArrB => 0xbfffdd5c
Run Code Online (Sandbox Code Playgroud)

对我来说,这表示3个不同的实例.

为什么"=="运算符会告诉我它们是相同的对象?

它是否是聪明的编译器优化?

--UPDATE--

鉴于以下答案,我仍然有点困惑:-).我会在这里扩展一下我的问题..

答案告诉我,"&arrayObject"获取变量的地址,而不是对象,我想这段代码告诉我这是真的:

NSLog(@"emptyArr => %p", &*emptyArr);
NSLog(@"emptyArrA => %p", &*emptyArrA);
NSLog(@"emptyArrB => %p", &*emptyArrB);
Run Code Online (Sandbox Code Playgroud)

因为它输出:

emptyArr => 0x6829fd0
emptyArrA => 0x6829fd0
emptyArrB => 0x6829fd0
Run Code Online (Sandbox Code Playgroud)

表示同一个对象.但这表明(至少对我来说)NSObject实例的"=="运算符中存在某种"魔力",它实际上使它比较指向变量后面的对象的指针而不是指向变量的指针.那是对的吗?

因为,如果我用"int*"做同样的事情,我必须取消引用它以获得相等.像这样:

int *i1 = malloc(sizeof(int));
*i1 = 42;
int *i2 = malloc(sizeof(int));
*i2 = 42;

NSLog(@"i1 == i2 => %d", (i1 == i2));
NSLog(@"*i1 == *i2 => %d", (*i1 == *i2));
Run Code Online (Sandbox Code Playgroud)

这给了我:

i1 == i2 => 0
*i1 == *i2 => 1
Run Code Online (Sandbox Code Playgroud)

这也是我对我(有点过时)C体验的期望:-)

Chu*_*uck 5

您的第二个测试采用变量的地址,并正确指示有三个不同的变量.所有三个变量都指向同一个空数组实例 - 作为优化,NSArray总是返回相同的空数组,并且arrayWithArray:在NSArrays上只保留参数,因为它是不可变的,因此无论如何它们都是无法区分的.如果要查看,请&在所有日志语句中取出运算符.如果你已经测试过&emptyArrA == &emptyArrB,那么你也会看到它也是假的.


回答你的新问题:不,没有魔力.这只是正常的指针相等.当你写somePointer == someOtherPointer,它总是告诉你他们是否指向同一个地址,不论类型- ,int,BOOL,NSMutableAttributedString*任何类型的.它比较指针中存储的地址.它绝不会比较指针的神奇指针.

我认为你缺少的是对象总是被指针引用 - 它们永远不是像int这样的直接值.要测试对象的值是否相等而不是指针相等,您需要一个类似的方法isEqual:.