这些是Cocoa数组对象(NSArray的实例),而不是C数组或C++向量,并且请记住Objective-C没有操作符重载。您可以使用对象的唯一功能是将其传递,存储在变量中并向其发送消息。
所以,在Objective-C对象中,数组下标运算符是错误的。我认为对Objective-C对象解除引用指针甚至在语言上也是无效的,因此这段代码应该会给你编译器错误。虽然我可能记错了。如果它确实到达运行时,那么这段代码迟早会崩溃,因为您正在访问超出数组对象末尾的内存。
(2013年的编辑:Objective-C现在支持对象下标。这最终转换为相应的
objectAtIndex:
或
replaceObjectAtIndex:withObject:
消息。因此,问题中的代码现在实际上可以工作,尽管这仍不是简单遍历数组,更不用说比较两个数组的正确方法。)
从NSArray对象中按索引检索对象的正确方法不是使用数组下标运算符,而是向数组对象发送
objectAtIndex:
消息:
[myArray objectAtIndex:i]
如果您不需要对数组对象执行其他操作(如替换可变数组中的对象),则迭代数组元素的正确方法是直接循环遍历它(这称为“快速枚举”):
for (MyObject *myObject in myArray) {
…
}
NSArray同样响应objectEnumerator
和reverseObjectEnumerator
,它们返回一个类似可迭代的对象。这两者中,reverseObjectEnumerator
在新代码中更为有用,因为你可以直接迭代数组以正向迭代。在快速枚举存在之前,这两种方式都非常有用;代码看起来像这样:
NSEnumerator *myArrayEnum = [myArray objectEnumerator];
MyObject *myObject;
while ((myObject = [myArrayEnum nextObject])) {
…
}
(是的,那是在条件语句中的赋值。故意这样做,因此多了一个()
。我们当时写代码很大胆,不是吗?)
不过,对于你正在做的事情,你更可能想要向其中一个数组发送 isEqualToArray:
消息,就像 Williham Totland 建议的那样:
BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray];
首先确保两个数组具有相同的长度,然后同时遍历它们,对每一对对象发送isEqual:
消息。如果每个isEqual:
消息都返回YES
,它将返回YES
;否则返回NO
。数组可能包含不同的对象,但只要每一对相等,数组本身就是相等的。
这假设您想进行对象相等性比较。如果两个独立的对象相等,则当您向其中一个对象发送isEqual:
消息并传递另一个对象时,其中一个对象会响应并返回YES
。如果您想比较对象的标识,则需要自己进行锁步循环,并使用==
运算符。
BOOL arraysContainTheSameObjects = YES;
NSEnumerator *otherEnum = [otherArray objectEnumerator];
for (MyObject *myObject in myArray) {
if (myObject != [otherEnum nextObject]) {
arraysContainTheSameObjects = NO;
break;
}
}
但这很不可能发生。大多数情况下,我想要测试对象的相等性而不是身份,所以isEqualToArray:
就是我想要的。
[nsArrrayInstance isEqual:otherInstance]
是否等同于[nsArrrayInstance isEqualToArray:otherInstance]
? - nmrisEqualTo...
可能会假定参数是正确的类型~ 我不确定第二个链接讨论的是哪种边缘情况。也许我可以麻烦您详细说明一下? - nmrisEqualTo<Type>:
方法中,nil
不是有效的参数,这些方法的实现在接收到nil
时可能会引发异常。然而,为了向后兼容,Cocoa框架的isEqual:
方法确实接受nil
,并返回NO
。” - Peter HoseyisEqualTo<Type>:
,那么不实现isEqual:
就会很奇怪?并且给定<Type>
类型的参数,它们应该返回相同的值? - nmr