这些是 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])) {
…
}
(是的,这是条件中的一个赋值。故意的,因此额外的()。我们当时大胆地编码,不是吗?)
不过,正如 Williham Totland 建议的那样,对于您正在做的事情,您更可能希望向其中一个数组发送 isEqualToArray: 消息:
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]) {
//We have found a pair of two different objects.
arraysContainTheSameObjects = NO;
break;
}
}
但这不太可能。大多数时候,我想测试对象的相等性,而不是身份,所以isEqualToArray: 是我想要的。