我在创建一个自定义对象数组的NSMutableArray到一个字典数组和单个字典数组(不在数组中)时遇到了问题。
我目前有一个Person对象的NSMutableArray。我遍历这些Person对象来创建每个对象的NSDictionaries。这些词典有三个键:
NSString *firstName;
NSString *lastName;
Person *id;
这些词典中的一些将具有完全相同的名字和姓氏,但是人物ID 总是不同。我想将此对象的NSMutableArray转换为NSMutableArrays和NSDictionaries的NSMutableArray - NSMutableArrays将是具有相同firstName和lastName的NSDictionaries,而单独的NSDictionaries将是没有firstName和lastName的对象与原始NSMutableArray中的任何其他Person共同。
我希望最终结果的视觉效果如下:
| |-- NSDictionary (john, smith, id)
| |-- NSDictionary (john, smith, id)
|-- NSMutableArray |-- NSDictionary (john, smith, id)
| |-- NSDictionary (john, smith, id)
| |-- NSDictionary (john, smith, id)
|
| |-- NSDictionary (bill, jones, id)
people |-- NSMutableArray |-- NSDictionary (bill, jones, id)
(NSMutableArray) | |-- NSDictionary (bill, jones, id)
|
|-- NSDictionary (mike, smith, id)
|
|-- NSDictionary (mike, jones, id)
|
|-- NSDictionary (john, jones, id)
我目前的实施情况如下:
- (NSMutableArray*)organizeForSearchResults:(NSMutableArray*)c {
NSMutableArray *returnArray = [NSMutableArray alloc] init];
// iterate through every person in the incoming crate
@autoreleasepool {
for (Person *person in c) {
// create a new person dictionary
NSDictionary *personDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:
person, @"person",
person.firstName, @"firstName",
record.lastName, @"lastName",
nil];
// if there are already objects in the top level c array
if (returnArray.count > 0) {
for (id object in returnArray) {
// the object in returnArray is an array of record dictionaries
if ([object isKindOfClass:[NSMutableArray class]]) {
// if the first dictionary object in the array has the same firstName
// and lastName, add the new person dict to the existing array of dicts
NSString *firstName = [(NSDictionary*)object[0] objectForKey:@"firstName"];
NSString *lastName = [(NSDictionary*)object[0] objectForKey:@"lastName"];
if ([firstName isEqualToString:person.firstName] && [lastName isEqualToString:person.lastName]) {
[object addObject:personDictionary];
}
}
// if the object is a person dictionary, see if it matches the current dictionary
else if ([object isKindOfClass:[NSDictionary class]]) {
NSString *firstName = [(NSDictionary*)object objectForKey:@"firstName"];
NSString *lastName = [(NSDictionary*)object objectForKey:@"lastName"];
// if the current object matches the new person dict, we need to
// create a new array with both the existing person dict and the
// new person dict, add that array to returnArray, and remove the
// old person dict
if ([firstName isEqualToString:record.firstName] && [lastName isEqualToString:record.lastName]) {
NSMutableArray *newArray = [[NSMutableArray alloc] initWithCapacity:2];
[newArray addObject:object];
[newArray addObject:personDictionary];
[returnArray addObject:newArray];
[returnArray removeObject:object];
}
// the new person dict does not match an existing array, so add it as
// a single item in personArray
else {
[personArray addObject:personDictionary];
}
}
}
}
// there are no objects in personArray, so just add this person dict
else {
[personArray addObject:personDictionary];
}
}
}
return personArray;
}
到目前为止,我的实现在功能上是正确的,我相信,但我显然会收到*** Collection <__NSArrayM:> was mutated while being enumerated.
错误,因为我在枚举时修改了NSMutableArray。我觉得我完全迷失了如何正确实现这一点 - 有没有人有另外一个如何实现这个目标的策略?
答案 0 :(得分:0)
我相信,到目前为止我的实现在功能上是正确的,
抱歉,但我认为你会发现它不是。然而,这是简单的调试,我相信你会把它整理出来。
但我显然得到了*** Collection&lt; __ NSArrayM:&gt;在被列举时被突变。错误
观察1:您可以通过改变枚举的数组来解决问题 - 即使用for(a in b)
样式迭代进行处理。如果您改为使用for(a; b; c)
来遍历数组的索引,那么可以随时改变数组,您也可以使用- replaceObjectAtIndex:withObject:
方法而不是{ {1}} / addObject:
对。
对迭代样式进行这样的更改不需要来修复您的问题,但这样做可能有意义。
观察2:您当前的迭代遍历整个数组,但是对于每次迭代执行,最多只进行一次更改 - 您将项添加到数组,或者替换字典元素带有数组元素。一旦你做了改变,就可以终止循环 - 其余的迭代不会做任何有用的事情。
但是,如果您使用removeObject:
样式,那些冗余迭代将执行一些不会有用的操作 - 它们会导致您在更改数组后尝试继续迭代时看到的错误。 / p>
for in
语句可用于终止迭代。如果在进行变异控制后使用其中一个,则在迭代后转移到语句。该语句适用于任何一种迭代方式。
这应该足以让你解决这个问题,但是你应该检查一下你的逻辑 - 它可能还没有达到预期的效果。
BTW您可能希望更改为现代Objective-C语法以进行字典构建和键索引,它会缩短您的代码并使其更具可读性。
HTH