【问题标题】:NSGenericException reason Collection <NSConcreteMapTable: xxx>NSGenericException 原因集合 <NSConcreteMapTable: xxx>
【发布时间】:2014-03-18 13:32:15
【问题描述】:

这是我在出现 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

【问题讨论】:

    标签: ios objective-c sprite-kit


    【解决方案1】:

    我有时会遇到同样的例外情况。它已经存在了一段时间,我已经尝试确定它好几个星期了。

    我怀疑它可能是由于预加载纹理而发生的,无论是手动还是由 Sprite Kit 自动触发,同时一些其他代码导致纹理被加载或访问。

    我已将我的 preloadTextures: 调用减少到一个,但我仍然遇到问题,只是频率降低了。我试图 performSelector:onMainThread: 每当我运行一个选择器,该选择器从completionBlock 或其他在不同线程上运行的代码中访问或加载图像(或可能只是在内部)。

    在我将用户界面代码移动到主线程(它是从完成处理程序中调用的)之后,我今天一整天都没有发生这种崩溃。我不能说 100% 确定这是否解决了它。

    我希望这会有所帮助。肯定有一些问题在发生,如果您执行po 0x1459da60(在 lldb 的命令窗口中,使用异常提供的地址),您会看到正在修改的是 SKTextureAtlas 纹理列表。我希望这可以帮助您查明问题出在哪里。

    【讨论】:

    • 很好的答案!非常感谢,所以你建议从 initWithSize 调用用户界面代码: [self performSelectorOnMainThread .. ] 对吗? ...而不仅仅是 [self aMethod]
    • 这更像是一种观察与预感,但一般来说,如果您怀疑某些代码与纹理加载并行运行(发生在后台),那么可能值得尝试运行该特定代码主线程上的代码,或者在调用纹理预加载完成处理程序之后。我仍然不能 100% 确定我的问题是否已解决,或者由于问题如此零星,究竟是什么解决了它。
    • 我确实在后台加载了纹理,其余的在主线程上,但没有任何改变:(
    • 现在我试图从 initWithSize 只加载纹理,在加载纹理后我调用加载 UI 的方法......但仍然不知道它是否会工作
    • 只能说我设法摆脱了错误。问题的一部分是在完成处理程序或其他回调块中堆叠代码,因为它们可能在单独的线程上运行。拥有一个单独的加载场景也可能会有所帮助,以确保在预加载纹理时没有其他代码在运行。
    【解决方案2】:

    据我所知,这是 sprite kit 方法中的一个 sprite kit 错误:

    preloadTextures: withCompletionHandler:
    

    我能够解决此问题的唯一方法是完全删除此方法。 根据苹果文档,如果您访问 size 属性,纹理也会被加载。 所以我的解决方法就是这样做:

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

    它不漂亮,但它有效!

    【讨论】:

    • 它至少解决了您的问题吗?还是您最终找到了另一种解决方案?
    • 这实际上也对我有用。我刚刚做了 NSLog(@"%f", texture.size.width);避免未使用的变量警告。
    【解决方案3】:

    当我尝试预加载两个简单的动画时,我遇到了同样的问题。我试图在字典中预加载动画,并准备好通过字符串键调用它们。这是我尝试过的

    -(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){}];
        }
    

    以便在我尝试预加载另一个之前完成第一次预加载。

    我不知道这是否是您的问题,但如果是,请告诉我们。

    【讨论】:

    • 感谢您的回答,我正在尝试解决在 initWithSize 中加载 SKTextureAtlas 的问题,并且在所有纹理都来自此纹理数组之后,无需预加载任何东西.. 这在没有崩溃和所有精灵的情况下都很好用看正确..但我不确定这是正确的方法
    【解决方案4】:

    在 Xcode 6.3 beta / Swift 1.2 中,同样的事情仍然发生在我身上。这是一个对我有用的临时修复程序。

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

    我实际上将它包装在一个函数中,以便所有预加载都通过它。这样,如果它在 SpriteKit 端得到修复,或者这种方法存在重大缺陷,我可以删除调度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 2016-05-03
      • 1970-01-01
      相关资源
      最近更新 更多