某些上下文:在我的可破坏的Cocos2D地形库中,其中一个功能是可折叠的地形。为了有效地折叠,我将像素已被更改的列存储在NSMutableSet中,该NSMutableSet包含包含整数的NSNumbers。我正在使用这种数据结构,因为我不想迭代重复的列。
我对如何遍历NSMutableSet的第一直觉是使用'for in'循环。
for (NSNumber * col in [alteredColumns allObjects]) { // Works
// for (NSNumber * col in alteredColumns) { // Crashes
int x = col.intValue;
bool shouldShift = false;
bool alphaFound = false;
for (int y = (size_.height -1); y >= 0; y--) {
if (!shouldShift) {
if ([self pixelAt:ccp(x,y)].a == 0) {
// Need to shift all pixels above one down
alphaFound = true;
} else if (alphaFound) {
didCollapse = shouldShift = true;
// Ensure the top pixel is alpha'ed out if a collapse will occur
[self setPixelAt:ccp(x,0) rgba:ccc4(0, 0, 0, 0)];
[self setPixelAt:ccp(x,(y+1)) rgba:[self pixelAt:ccp(x,y)]];
} // end inner if
} else {
// Need to shift pixels down one
[self setPixelAt:ccp(x,(y+1)) rgba:[self pixelAt:ccp(x,y)]];
} // end if
} // end inner for
// Remove column from cache if no pixels collapsed
if (!shouldShift) [alteredColumns removeObject:col];
} // end outer for
然而,这导致了糟糕的结果。程序将因Bad Access Memory错误而崩溃。如果我改变for循环使用[changedColumns allObjects],那么一切正常。所以问题......'for in'循环不能用于无序集合,例如NSMutableSet吗?如果我必须使用像allObjects这样的方法,这有效吗?
提前致谢!
答案 0 :(得分:3)
if (!shouldShift) [alteredColumns removeObject:col]; //1
在此行中,您修改alteredColumns
。枚举时修改集合是一件坏事,坏事。如果你很幸运,你会得到BAD_ACCESS,最糟糕的是你甚至不会注意到出现问题,直到你完全出乎意料的行为。
for (NSNumber * col in [alteredColumns allObjects]) //2
在这里创建一个NSArray([NSSet allObjects]
返回一个NSArray),并枚举这个数组。在第1行修改alteredColumns
时,枚举数组不会发生变异。
for (NSNumber * col in alteredColumns) { //3
使用此行,您将枚举changedColumns, 在行// 1中进行了修改。
答案 1 :(得分:1)
- (void)enumerateObjectsUsingBlock:(void (^)(id obj, BOOL *stop))block