NSGenericException reason Collection <NSConcreteMapTable: xxx>

this is an error that I see with SKScene , this error occurs randomly and cannot be replicated

* Application termination due to an uncaught exception "NSGenericException", reason: '* NSConcreteMapTable: 0x1459da60> was mutated during enumeration. ''

what happened?

tell me if you need any other information

thanks

EDIT:

 *** First throw call stack: ( 0 CoreFoundation 0x025601e4 __exceptionPreprocess + 180 1 libobjc.A.dylib 0x022298e5 objc_exception_throw + 44 2 CoreFoundation 0x025efcf5 __NSFastEnumerationMutationHandler + 165 3 Foundation 0x01e47f03 -[NSConcreteMapTable countByEnumeratingWithState:objects:count:] + 66 4 CoreFoundation 0x0253d77f -[__NSFastEnumerationEnumerator nextObject] + 143 5 SpriteKit 0x01d009f2 +[SKTextureAtlas(Internal) findTextureNamed:] + 232 6 SpriteKit 0x01cf709c __26-[SKTexture loadImageData]_block_invoke + 1982 7 SpriteKit 0x01d34d09 _Z14SKSpinLockSyncPiU13block_pointerFvvE + 40 8 SpriteKit 0x01cf6898 -[SKTexture loadImageData] + 228 9 SpriteKit 0x01cf65d9 __51+[SKTexture preloadTextures:withCompletionHandler:]_block_invoke + 241 10 libdispatch.dylib 0x02b117b8 _dispatch_call_block_and_release + 15 11 libdispatch.dylib 0x02b264d0 _dispatch_client_callout + 14 12 libdispatch.dylib 0x02b14eb7 _dispatch_root_queue_drain + 291 13 libdispatch.dylib 0x02b15127 _dispatch_worker_thread2 + 39 14 libsystem_c.dylib 0x02de1e72 _pthread_wqthread + 441 15 libsystem_c.dylib 0x02dc9daa start_wqthread + 30 ) libc++abi.dylib: terminating with uncaught exception of type NSException 
+7
ios objective-c sprite-kit
source share
4 answers

I get the same exception. It was a while, and I tried to identify it for several weeks.

My suspicion is that this may be due to preloading the textures manually or automatically by the Sprite Kit, while other code causes loading or accessing the textures.

I cut my preloadTextures: calls by one, but I still get this problem less often. I tried to execute Selector: onMainThread: whenever I run a selector that accesses or loads images (or just maybe internally) from inside a completion block or other code that runs in another thread.

I did not have this failure all day today after I moved the code of my user interface to the main thread (it was called from the completion handler). I can’t say that 100% are sure that this is fixed.

Hope this helps a bit. Something definitely happens there, and if you do po 0x1459da60 (in the lldb command window, using the address provided by the exception), you will see that the SKTextureAtlas texture list changes. I hope this helps you determine where the problem is from your side.

+4
source share

From what I can tell, this is a sprite set error in the sprite set method:

 preloadTextures: withCompletionHandler: 

The only way I could fix this is to completely remove this method. According to apple documents, textures are also loaded if you get access to the size property. So my way is to do just that:

 for (SKTexture *texture in self.texturesArray) { texture.size; } 

It is not very, but it works!

+4
source share

I had the same problem when I tried to preload two simple animations. I tried to preload the animation in the dictionary and prepare them for calling with a string key. Here is what I tried

 -(void)setupAnimDict { animDict = [[NSMutableDictionary alloc] init]; [animDict setObject:[self animForName:@"blaze" frames:4] forKey:@"blaze"]; [animDict setObject:[self animForName:@"flame" frames:4] forKey:@"flame"]; } -(SKAction *)animForName:(NSString *)name frames:(int)frames { NSArray *animationFrames = [self setupAnimationFrames:name base:name num:frames]; SKAction *animationAction = [SKAction animateWithTextures:animationFrames timePerFrame:0.10 resize:YES restore:NO]; return [SKAction repeatActionForever:animationAction]; } -(NSArray *)setupAnimationFrames:(NSString *)atlasName base:(NSString *)baseFileName num:(int)numberOfFrames { [self preload:baseFileName num:numberOfFrames]; NSMutableArray *frames = [NSMutableArray arrayWithCapacity:numberOfFrames]; SKTextureAtlas *atlas = [SKTextureAtlas atlasNamed:atlasName]; for (int i = 0; i < numberOfFrames; i++) { NSString *fileName = [NSString stringWithFormat:@"%@%01d.png", baseFileName, i]; [frames addObject:[atlas textureNamed:fileName]]; } return frames; } -(void)preload:(NSString *)baseFileName num:(int)numberOfFrames { NSMutableArray *frames = [NSMutableArray arrayWithCapacity:numberOfFrames]; for (int i = 0; i < numberOfFrames; i++) { NSString *fileName = [NSString stringWithFormat:@"%@%01d.png", baseFileName, i]; [frames addObject:[SKTexture textureWithImageNamed:fileName]]; } [SKTexture preloadTextures:frames withCompletionHandler:^(void){}]; } 

When I called the setupDict method, I sometimes got the same error as you. The problem was that preloading my two animations collided with each other. I got rid of the error by changing

 [SKTexture preloadTextures:frames withCompletionHandler:^(void){}]; 

to

 if ([baseFileName isEqualToString:@"blaze"]) { [SKTexture preloadTextures:frames withCompletionHandler:^{ [self setupFlame]; }]; } else { [SKTexture preloadTextures:frames withCompletionHandler:^(void){}]; } 

so that the first preload is done before I try to preload another one.

I do not know if this is your problem, but if it is given to us to know.

+2
source share

The same thing happens to me in Xcode 6.3 beta / Swift 1.2. Here is a workaround that worked for me.

 SKTextureAtlas.preloadTextureAtlases([SKTextureAtlas(named: "testAtlas")], withCompletionHandler: { dispatch_async(dispatch_get_main_queue(), { handler() }) }) 

I actually wrapped this in a function so that all the preloads go through it. That way, if it is installed on the SpriteKit side or if there are serious flaws in this approach, I can remove the submission.

+1
source share

All Articles