Коллекция причины NSGenericException <NSConcreteMapTable: xxx>
Это ошибка, которую я вижу, когда присутствует SKScene
эта ошибка возникает случайно и не может быть воспроизведена
* Завершение работы приложения из-за неисследованного исключения "NSGenericException", причина: "* Коллекция
что случилось?
скажите мне, если вам нужна другая информация
Спасибо
РЕДАКТИРОВАТЬ:
*** 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
4 ответа
Иногда я получаю такое же исключение. Это было вокруг некоторое время, и я пытался определить это в течение нескольких недель.
Я подозреваю, что это может произойти из-за предварительной загрузки текстур, либо вручную, либо автоматически запускаемой Sprite Kit, в то время как другой код вызывает загрузку или доступ к текстурам.
Я сократил свои preloadTextures: звонки до одного, но я все еще получаю проблему, только реже. Я пытался выполнить Selector: onMainThread: всякий раз, когда я запускаю селектор, который получает доступ или загружает изображения (или просто может внутренне) изнутри CompleteBlock или другого кода, который выполняется в другом потоке.
У меня не было этого сбоя весь день сегодня после того, как я переместил свой код пользовательского интерфейса в основной поток (он вызывался из обработчика завершения). Я не могу сказать на 100% наверняка, исправило ли это все же.
Надеюсь, это немного поможет. Там определенно что-то привередливое происходит, и если вы делаете po 0x1459da60
(в окне команд lldb, используя адрес, указанный в исключении), вы увидите, что это текстовый список SKTextureAtlas, который изменяется. Я надеюсь, что это поможет вам точно определить, откуда возникла проблема с вашей стороны.
Из того, что я могу сказать это ошибка набора спрайтов в методе набора спрайтов:
preloadTextures: withCompletionHandler:
Единственный способ, которым я смог это исправить, это полное удаление этого метода. Согласно документам Apple, текстуры также загружаются, если вы получаете доступ к size
имущество. Так что мой обходной путь - сделать именно это:
for (SKTexture *texture in self.texturesArray) {
texture.size;
}
Это не красиво, но это работает!
У меня была такая же проблема, когда я пытался предварительно загрузить две простые анимации. Я попытался предварительно загрузить анимацию в словарь и подготовить ее к вызову через строковый ключ. Вот что я пробовал
-(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){}];
}
Когда я вызывал метод setupDict, я иногда получал ту же ошибку, что и вы. Проблема состояла в том, что предварительная загрузка двух моих анимаций сталкивалась друг с другом. Я избавился от ошибки, изменив
[SKTexture preloadTextures:frames withCompletionHandler:^(void){}];
в
if ([baseFileName isEqualToString:@"blaze"]) {
[SKTexture preloadTextures:frames withCompletionHandler:^{
[self setupFlame];
}];
} else {
[SKTexture preloadTextures:frames withCompletionHandler:^(void){}];
}
так что первая предварительная загрузка была сделана до того, как я попытался предварительно загрузить другую.
Я не знаю, если это ваша проблема, но если это так, дайте нам знать.
То же самое по-прежнему происходит для меня в Xcode 6.3 beta / Swift 1.2. Вот временное исправление, которое сработало для меня.
SKTextureAtlas.preloadTextureAtlases([SKTextureAtlas(named: "testAtlas")], withCompletionHandler: {
dispatch_async(dispatch_get_main_queue(), {
handler()
})
})
Я фактически обернул это в функцию, чтобы все предварительные загрузки проходили через нее. Таким образом, если это исправлено на стороне SpriteKit, или если при таком подходе есть серьезные недостатки, я могу удалить диспетчеризацию.