2015-03-25 3 views
1

У меня возникают проблемы со следующим кодом, который загружает SKTexture, вызывая его размер. Кодирует случайным образом около 1 из каждых 100 запусков в строке, где вызывается размер. Существуют некоторые другие методы SKTexture для предварительной загрузки изображений, но они также вызывают сбои еще чаще! Я использую TextureAtlases и для предотвращения сбоя все мои нагрузки SKTexure происходят с помощью этого метода.Загрузка SKTexutre Crash с мутированием при перечислении

/* add image to dictionary thread-safe */ 
-(SKTexture*) getThreadSafeDictionaryContainImageOtherwiseLoadAndReturn:(NSString*) imageToLoad andForceLoad:(BOOL) forceLoad{ 

    // to control the enviroment where the image dictionary is modified, go ahead and lock it down with an NSLock 
    [self.dictionaryModificationLock lock]; 

    SKTexture *toReturn = nil; 
    CGSize size = CGSizeZero; 

    // first, ignore duplicate loads by looking for the image in an NSDictionary called "allImages" 
    if ((toReturn = [self.allImages objectForKey:imageToLoad])){ 
     // have the image to return already loaded 

    }else{ 
     // grab the SKTexture and force it to load by requesting it's size 
     SKTexture *texture = [SKTexture textureWithImageNamed:imageToLoad]; 
     if (forceLoad) 
      size = texture.size; // crashes here! 

     [self.allImages setObject:texture forKey:imageToLoad]; 
     toReturn = texture; 
    } 

    [self.dictionaryModificationLock unlock]; // unlock the NSLock 
    return toReturn; 
} 

Вот что отчет аварии выглядит следующим образом:

Fatal Exception: NSGenericException 
*** Collection <NSConcreteMapTable: 0x1c059ff0> was mutated while being enumerated. 

0 CoreFoundation __exceptionPreprocess + 126 
2 CoreFoundation -[NSException name] 
3 Foundation -[NSConcreteMapTable countByEnumeratingWithState:objects:count:] + 56 
4 CoreFoundation -[__NSFastEnumerationEnumerator nextObject] + 110 
5 SpriteKit +[SKTextureAtlas(Internal) findTextureNamed:] + 284 
6 SpriteKit __26-[SKTexture loadImageData]_block_invoke + 1654 
7 SpriteKit SKSpinLockSync(int*, void() block_pointer) + 104 
8 SpriteKit -[SKTexture loadImageData] + 302 
9 SpriteKit -[SKTexture size] + 42 

Я нашел некоторые другие темы, говоря, что это проблема с SpriteKit. Но я думаю, что вокруг должна быть какая-то работа. Ребята, что вы думаете?

Спасибо,

Гаррен

ответ

0

Сво ошибка

Это, безусловно, выглядит как ошибка в SpriteKit. Вы можете попытаться предварительно загрузить изображение сначала, оно может закончиться отдельным контуром кода. Его возможная предварительная загрузка поможет предотвратить это.

https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html#//apple_ref/doc/uid/TP40013043-CH9-SW21

Atlas

Если вы не сделали этого, рассмотреть возможность использования текстуры атласа и поджимать все ваши активы там.

https://developer.apple.com/library/ios/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/Sprites/Sprites.html#//apple_ref/doc/uid/TP40013043-CH9-SW15

Запирание

примечание стороны, и я не думаю, что это будет решить вашу аварию на всех, но с использованием @synchronized для блокировки более семантическим.

Вместо того, чтобы иметь NSLock, просто заверните текущий код блокировки в @synchronized(self). Если у вас есть соперничество с другими частями кода, которые также блокируются самостоятельно, вы можете создать отдельный объект id textureLockObject.

Apple может и будет оптимизировать @синхронизированный код, а не использовать NSLocks.

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html#//apple_ref/doc/uid/10000057i-CH8-SW3

Смежные вопросы