cocos2d cannot add child asynchronously
-
24-06-2021 - |
Question
I need to retrieve some data from a database to display on the screen. I want to avoid the application from blocking so I display the next screen before I retrieve any data and add the data as it comes in.
This is the method that adds the info I need on-screen:
- (void)initInfo
{
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCMenu *infoMenu;
// get the info in seperate thread since it may block
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
infoMenu = [PlayerInfoHelper generateInfoForPlayerWithId:[PlayerManager sharedInstance].activePlayer.objectId tag:-1 sender:self];
dispatch_async(dispatch_get_main_queue(), ^{
if (infoMenu != nil) {
infoMenu.position = ccp(winSize.width - kSSInfoPaddingX, winSize.height - kSSInfoPaddingY);
[self addChild:infoMenu z:zIndex++]; // (1)
}
});
});
}
The method generateInfoForPlayerWithId:tag:sender: might block, that is the reason why I put it in its own thread. I add the menu in the main thread, since it is a UI-update.
I am sure infoMenu is a correct CCMenu* object.
I am getting a EXC_BAD_ACCESS when I do not comment out the line indicated with // (1).
Solution
To run Cocos2D in a background thread you need to create a new EAGLContext. Like this:
- (void)createMySceneInBackground
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
EAGLContext *k_context = [[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1 sharegroup:[[[[CCDirector sharedDirector] openGLView] context] sharegroup]] autorelease];
[EAGLContext setCurrentContext:k_context];
if (infoMenu != nil) {
infoMenu.position = ccp(winSize.width - kSSInfoPaddingX, winSize.height - kSSInfoPaddingY);
[self addChild:infoMenu z:zIndex++]; // (1)
}
[pool release];
}
Good luck!
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow