我有一个NSMutableArray,它持有一个对象列表。我想要做的是迭代这个对象列表,找到我想要插入的匹配对象。一旦找到匹配的对象,我就想简单地用我想要插入的对象替换当前列表中的对象。我试图使用快速枚举来做到这一点:
TestResult *result = [[TestResult alloc] init];
[result setName:name];
[result setScore:score];
[result setDateStamp:date];
for (TestResult *checkTest in [DataModel sharedInstance].testResultList) {
NSInteger indx = [[DataModel sharedInstance].testResultList indexOfObjectPassingTest:^BOOL(TestResult *obj, NSUInteger idx, BOOL *stop) {
return [obj.name isEqualToString:name];
}];
if (indx != NSNotFound) {
[[DataModel sharedInstance].testResultList replaceObjectAtIndex:indx withObject:result];
}
}
不幸的是,当我运行上面的代码时,我收到以下错误:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x9624820> was mutated while being enumerated.'
任何人都可以看到我做错了什么,以及如何解决这个问题,还能实现我上面描述的功能?
答案 0 :(得分:4)
首先,崩溃是非常自我解释的。 您实际上是在变异(也就是更换数组中的对象),而快速枚举仍在进行中,这是不允许的。
如果你选择你的设计,那么解决方案就是实际捕获对象的索引,打破快速枚举并替换快速枚举之外的对象。
然而,你所做的并不正确。 使用indexOfObjectPassingTest的方法是:
NSInteger indx = [[DataModel sharedInstance].testResultList indexOfObjectPassingTest:^BOOL(TestResult *obj, NSUInteger idx, BOOL *stop) {
return [obj.name isEqualToString:name];
}];
if (indx != NSNotFound) {
[[DataModel sharedInstance].testResultList replaceObjectAtIndex:indx withObject:result];
}
您无需手动枚举数组的所有元素。 该功能在内部为您完成。
答案 1 :(得分:0)
如错误消息所示,您无法编辑正在枚举的数组。你需要有一个不同的数组,然后你就可以做到这一点。
以下内容可行,
TestResult *result = [[TestResult alloc] init];
[result setName:name];
[result setScore:score];
[result setDateStamp:date];
NSArray *array = [NSArray arrayWithArray:[DataModel sharedInstance].testResultList];
for (TestResult *checkTest in array) {
NSInteger indx = [[DataModel sharedInstance].testResultList indexOfObjectPassingTest:^BOOL(TestResult *obj, NSUInteger idx, BOOL *stop) {
return [obj.name isEqualToString:name];
}];
if (indx != NSNotFound) {
[[DataModel sharedInstance].testResultList replaceObjectAtIndex:indx withObject:result];
}
}
<强>更新强>
根据Lefteris的评论,如果使用indexOfObjectPassingTest
方法,则无需迭代数组。
你可以简单地使用,
TestResult *result = [[TestResult alloc] init];
[result setName:name];
[result setScore:score];
[result setDateStamp:date];
NSInteger indx = [[DataModel sharedInstance].testResultList indexOfObjectPassingTest:^BOOL(TestResult *obj, NSUInteger idx, BOOL *stop) {
return [obj.name isEqualToString:name];
}];
if (indx != NSNotFound) {
[[DataModel sharedInstance].testResultList replaceObjectAtIndex:indx withObject:result];
}
答案 2 :(得分:0)
如错误消息所示,您无法修改foreach bucle中使用的数组。将您的代码更改为:
TestResult *result = [[TestResult alloc] init];
[result setName:name];
[result setScore:score];
[result setDateStamp:date];
NSInteger indx = NSNotFound;
for (TestResult *checkTest in [DataModel sharedInstance].testResultList) {
indx = [[DataModel sharedInstance].testResultList indexOfObjectPassingTest:^BOOL(TestResult *obj, NSUInteger idx, BOOL *stop) {
return [obj.name isEqualToString:name];
}];
}
if (indx != NSNotFound) {
[[DataModel sharedInstance].testResultList replaceObjectAtIndex:indx withObject:result];
}
答案 3 :(得分:0)
枚举时,不能替换,删除或插入数组中的元素。但您可以将idxn
处元素的所有属性更改为result
的属性。这样就可以保留物体了。
希望这有帮助!