可能重复:
Getting exception as “Collection was mutated while being enumerated”
此问题是我之前发布的另一个问题的延续How to read in plist data into a data model? @ devdavid帮助我做到这一点......
我有一个名为“HotelList.plist”的plist文件,它看起来像这样:
<array>
<dict>
<key>hotelID</key>
<integer>0</integer>
<key>name</key>
<string>Solmar</string>
// ... more keys and strings ...
</dict>
// ... more hotel entries ...
</array>
我有一个描述钥匙的“酒店”课程。 我有一个数据模型类,我想在这个plist中读到一个数组。
#import "DataModel.h"
#import "Hotel.h"
// Private methods
@interface DataModel ()
@property (nonatomic, retain) NSMutableArray *hotels;
-(void)loadHotels;
@end
@implementation DataModel
@synthesize hotels;
- (id)init {
if ((self = [super init])) {
[self loadHotels];
}
return self;
}
- (void)dealloc {
[hotels release];
[super dealloc];
}
- (void)loadHotels {
NSBundle* bundle = [NSBundle mainBundle];
NSString* plistpath = [bundle pathForResource:@"HotelList" ofType:@"plist"];
hotels = [[NSMutableArray arrayWithContentsOfFile:plistpath]retain];
for (NSDictionary *hotelDict in hotels) {
Hotel *hotel = [[Hotel alloc] init];
hotel.hotelID = [[hotelDict objectForKey:@"hotelID"] intValue];
hotel.name = [hotelDict objectForKey:@"name"];
[hotels addObject:hotel];
[hotel release];
}
}
@end
当我运行时,调试器向我显示每个酒店字典都被读入但是当它到达plist的末尾(我有大约30家酒店)时,它会尝试回到第一个并且崩溃,给出一个例外情况“收集在被枚举时发生变异”。
绿色SIGABRT指示停在
上for (NSDictionary *hotelDict in hotels) {
线。我的for循环有问题吗?我设置数组/字典的方式?或者也许plist的格式是错误的(虽然我不这么认为,因为调试器显示我正在正确读取它)?
为了完整起见,我应该提一下,是的,plist文件存在且位于mainBundle中,拼写正确。此外,plist中的数据是静态的 - 我不必为文件保存任何新内容。
请帮忙!
答案 0 :(得分:2)
使用访问者,而不是直接使用ivars。你的问题会更加明显,你可以避免在hotel
的分配中可能发生的泄漏(如果第二次调用loadHotels
)。您的代码将字典读入数组,然后尝试将Hotel
个对象附加到同一个数组中。这就是你真正要说的话:
NSArray *hotelDicts = [[NSArray alloc] initWithContentsOfFile:plistpath];
self.hotels = [NSMutableArray array];
for (NSDictionary *hotelDict in hotelDicts) {
Hotel *hotel = [[Hotel alloc] init];
hotel.hotelID = [[hotelDict objectForKey:@"hotelID"] intValue];
hotel.name = [hotelDict objectForKey:@"name"];
[self.hotels addObject:hotel];
[hotel release];
}
[hotelDicts release];
答案 1 :(得分:1)
您正在尝试修改您正在枚举的集合 - 您无法执行此操作。而不是使用枚举器,尝试迭代集合。当您遍历数组时,您仍然可以添加/删除数组成员,因为您没有绑定在开始 for block 之前定义的枚举。
迭代集合的一种方法是使用简单的for循环:
for( int i = 0; i < [array count]; i++ )
{
id object = [array objectAtIndex:i];
// do something with object
}