这些是 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
and reverseObjectEnumerator
,它返回一个类似的可迭代对象。两者中,reverseObjectEnumerator
在新代码中更有用,因为您可以直接迭代数组以向前迭代。在快速枚举存在之前,它们都是最有用的;该代码如下所示:
NSEnumerator *myArrayEnum = [myArray objectEnumerator];
MyObject *myObject;
while ((myObject = [myArrayEnum nextObject])) {
…
}
(是的,这是条件中的一个赋值。故意,因此额外的()
。我们当时大胆地编码,不是吗?)
但是,对于您正在做的事情,您更可能希望向其中一个数组发送isEqualToArray:
消息,正如 Williham Totland 建议的那样:
BOOL theyAreEqual = [myFirstArray isEqualToArray:mySecondArray];
这将确保两个数组具有相同的长度,然后以锁步方式遍历它们,发送isEqual:
到每对对象。YES
如果每条isEqual:
消息都返回,它将返回YES
;NO
否则。数组可能包含不同的对象,但只要每一对相等,数组本身就相等。
假设您想要对象相等。YES
如果其中一个在您向其发送isEqual:
消息并传递另一个对象时响应,则两个单独的对象是相等的。如果您打算比较对象的身份,那么您确实需要自己执行锁步循环并使用==
:
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:
就是我想要的。